using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using Peak.Network;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using UnityEngine;
using Zorro.Settings;
using com.quackandcheese.LocalMultiplayer.Helpers;
using com.quackandcheese.LocalMultiplayer.Objects;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Ashley.MeshSplitter")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: IgnoresAccessChecksTo("DemiLib")]
[assembly: IgnoresAccessChecksTo("DOTween")]
[assembly: IgnoresAccessChecksTo("DOTweenPro")]
[assembly: IgnoresAccessChecksTo("HBAO.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Demos")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("pworld")]
[assembly: IgnoresAccessChecksTo("sc.posteffects.runtime")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Tayx.Graphy")]
[assembly: IgnoresAccessChecksTo("unity-websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Cinemachine")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.RebindingUI")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")]
[assembly: IgnoresAccessChecksTo("Unity.Localization")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.MemoryProfiler")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Center.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Playmode.Common.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Playmode")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Rendering.LightTransport.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime.Shared")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.GPUDriven.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.2D.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Shaders")]
[assembly: IgnoresAccessChecksTo("Unity.ResourceManager")]
[assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication.PlayerAccounts")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Multiplayer")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Wire.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Splines")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AMDModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GraphicsStateCollectionSerializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HierarchyCoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputForUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MarshallingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MultiplayerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ShaderVariantAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityTestProtocolModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")]
[assembly: IgnoresAccessChecksTo("UnityUIExtensions")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.AutoLOD")]
[assembly: IgnoresAccessChecksTo("Zorro.ControllerSupport")]
[assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.JiggleBones")]
[assembly: IgnoresAccessChecksTo("Zorro.PhotonUtility")]
[assembly: IgnoresAccessChecksTo("Zorro.Settings.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.UI.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.quackandcheese.LocalMultiplayer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4+6fa95029dda180d27ff10d1625b0e1f2569aa3da")]
[assembly: AssemblyProduct("com.quackandcheese.LocalMultiplayer")]
[assembly: AssemblyTitle("LocalMultiplayer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace LocalMultiplayer.Patches
{
[HarmonyPatch(typeof(NetworkingUtilities))]
internal static class NetworkingUtilitiesPatch
{
[HarmonyPatch("LoadUserID")]
[HarmonyPrefix]
private static bool LoadUserIDPatch(ref AuthenticationValues __result)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
__result = new AuthenticationValues
{
AuthType = (CustomAuthenticationType)255,
UserId = Guid.NewGuid().ToString()
};
return false;
}
}
}
namespace com.quackandcheese.LocalMultiplayer
{
internal static class ConfigManager
{
public static ConfigFile ConfigFile { get; private set; }
public static ConfigEntry<bool> ExtendedLogging { get; private set; }
public static ConfigEntry<string> Photon_AppIdRealtime { get; private set; }
public static ConfigEntry<string> Photon_AppIdVoice { get; private set; }
public static void Initialize(ConfigFile configFile)
{
ConfigFile = configFile;
BindConfigs();
}
private static void BindConfigs()
{
ExtendedLogging = ConfigFile.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging.");
Photon_AppIdRealtime = ConfigFile.Bind<string>("Photon", "AppIdRealtime", "", "The App ID of your Photon Pun application.");
Photon_AppIdVoice = ConfigFile.Bind<string>("Photon", "AppIdVoice", "", "The App ID of your Photon Voice application.");
}
}
[BepInPlugin("com.quackandcheese.LocalMultiplayer", "LocalMultiplayer", "1.0.4")]
public class Plugin : BaseUnityPlugin
{
public const string Id = "com.quackandcheese.LocalMultiplayer";
internal static ManualLogSource Log { get; private set; }
internal static Plugin Instance { get; private set; }
internal static ConfigFile Config { get; private set; }
internal static Harmony? Harmony { get; set; }
public static string Name => "LocalMultiplayer";
public static string Version => "1.0.4";
private void Awake()
{
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Config = Utils.CreateGlobalConfigFile((BaseUnityPlugin)(object)this);
Patch();
ConfigManager.Initialize(Config);
Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
}
internal void Patch()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
if (Harmony == null)
{
Harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
}
Log.LogDebug((object)"Patching...");
Harmony.PatchAll();
Log.LogDebug((object)"Finished patching!");
}
}
internal static class SteamAccountManager
{
public static SteamAccount SpoofAccount;
private static bool _initialized;
public static SteamAccount RealAccount { get; private set; }
public static bool IsUsingSpoofAccount => SpoofAccount != default(SteamAccount);
public static void Initialize()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (!_initialized)
{
RealAccount = new SteamAccount(SteamFriends.GetPersonaName(), SteamUser.GetSteamID().m_SteamID);
CreateSpoofAccounts();
Application.quitting += UnassignSpoofAccount;
_initialized = true;
}
}
private static void CreateSpoofAccounts()
{
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccounts.Value;
int num = 5;
if (value.Count < num)
{
for (int i = value.Count; i < num; i++)
{
value.Add(new SteamAccount($"Player {i + 2}", SteamHelper.GenerateRandomSteamId()));
}
GlobalSaveHelper.SpoofSteamAccounts.Value = value;
}
}
public static void AssignSpoofAccount()
{
if (!IsUsingSpoofAccount)
{
SteamAccount availableSpoofAccount = GetAvailableSpoofAccount();
AddSpoofAccountInUse(availableSpoofAccount);
SpoofAccount = availableSpoofAccount;
PhotonNetwork.NickName = availableSpoofAccount.Username;
}
}
public static void UnassignSpoofAccount()
{
if (IsUsingSpoofAccount)
{
RemoveSpoofAccountInUse(SpoofAccount);
SpoofAccount = default(SteamAccount);
PhotonNetwork.NickName = RealAccount.Username;
}
}
public static void ResetSpoofAccountsInUse()
{
GlobalSaveHelper.SpoofSteamAccountsInUse.Value = new List<SteamAccount>();
}
public static bool TryGetSpoofAccount(ulong steamId, out SteamAccount steamAccount)
{
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccounts.Value;
foreach (SteamAccount item in value)
{
if (item.SteamId == steamId)
{
steamAccount = item;
return true;
}
}
steamAccount = default(SteamAccount);
return false;
}
private static void UpdateCurrentSpoofAccountData()
{
if (!IsUsingSpoofAccount)
{
return;
}
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccounts.Value;
for (int i = 0; i < value.Count; i++)
{
if (value[i] == SpoofAccount)
{
value[i] = SpoofAccount;
break;
}
}
GlobalSaveHelper.SpoofSteamAccounts.Value = value;
}
private static List<SteamAccount> GetAvailableSpoofAccounts()
{
List<SteamAccount> list = new List<SteamAccount>();
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccountsInUse.Value;
foreach (SteamAccount item in GlobalSaveHelper.SpoofSteamAccounts.Value)
{
if (!value.Contains(item))
{
list.Add(item);
}
}
return list;
}
private static SteamAccount GetAvailableSpoofAccount()
{
List<SteamAccount> availableSpoofAccounts = GetAvailableSpoofAccounts();
if (availableSpoofAccounts.Count == 0)
{
Plugin.Log.LogWarning((object)"SteamHelper: No cached spoof steam accounts available. Generating new spoof steam account.");
return new SteamAccount($"Player {Random.Range(100, 999)}", SteamHelper.GenerateRandomSteamId());
}
return availableSpoofAccounts[0];
}
private static void AddSpoofAccountInUse(SteamAccount account)
{
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccountsInUse.Value;
if (!value.Contains(account))
{
value.Add(account);
GlobalSaveHelper.SpoofSteamAccountsInUse.Value = value;
}
}
private static void RemoveSpoofAccountInUse(SteamAccount account)
{
List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccountsInUse.Value;
if (value.Contains(account))
{
value.Remove(account);
GlobalSaveHelper.SpoofSteamAccountsInUse.Value = value;
}
}
}
internal static class Utils
{
public static string GetPluginPersistentDataPath()
{
return Path.Combine(Application.persistentDataPath, Plugin.Name);
}
public static ConfigFile CreateConfigFile(BaseUnityPlugin plugin, string path, string name = null, bool saveOnInit = false)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin);
if (name == null)
{
name = metadata.GUID;
}
name += ".cfg";
return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata);
}
public static ConfigFile CreateLocalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false)
{
return CreateConfigFile(plugin, Paths.ConfigPath, name, saveOnInit);
}
public static ConfigFile CreateGlobalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false)
{
string pluginPersistentDataPath = GetPluginPersistentDataPath();
if (name == null)
{
name = "global";
}
return CreateConfigFile(plugin, pluginPersistentDataPath, name, saveOnInit);
}
}
}
namespace com.quackandcheese.LocalMultiplayer.Patches
{
[HarmonyPatch(typeof(MainMenu))]
internal static class MenuPageMainPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void StartPatch()
{
SteamAccountManager.UnassignSpoofAccount();
}
[HarmonyPatch("PlaySoloClicked")]
[HarmonyPrefix]
private static bool PlaySoloClickedPatch(ref MainMenu __instance)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
SteamAccountManager.AssignSpoofAccount();
PhotonNetworkHelper.SetPhotonServerSettings();
GameHandler.GetService<SteamLobbyHandler>().TryJoinLobby(new CSteamID(GlobalSaveHelper.SteamLobbyId.Value));
return false;
}
}
[HarmonyPatch(typeof(NetworkConnector))]
internal static class NetworkConnectorPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void StartPatch()
{
PhotonNetworkHelper.SetPhotonServerSettings();
}
}
[HarmonyPatch(typeof(SettingsHandler))]
internal static class SettingsHandlerPatch
{
[HarmonyPatch("SaveSetting")]
[HarmonyPrefix]
private static bool SaveSettingPatch(ref Setting setting)
{
if (!SteamAccountManager.IsUsingSpoofAccount)
{
return true;
}
return false;
}
}
[HarmonyPatch]
internal static class SteamClientPatch
{
[HarmonyPatch(typeof(SteamFriends), "GetPersonaName")]
[HarmonyPrefix]
private static bool GetPersonaNamePatch(ref string __result)
{
if (!SteamAccountManager.IsUsingSpoofAccount)
{
return true;
}
__result = SteamAccountManager.SpoofAccount.Username;
return false;
}
[HarmonyPatch(typeof(SteamUser), "GetSteamID")]
[HarmonyPrefix]
private static bool GetSteamIDPatch(ref CSteamID __result)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
if (!SteamAccountManager.IsUsingSpoofAccount)
{
return true;
}
__result = new CSteamID(SteamAccountManager.SpoofAccount.SteamId);
return false;
}
}
[HarmonyPatch(typeof(SteamLobbyHandler))]
internal static class SteamLobbyHandlerPatch
{
[HarmonyPatch("OnLobbyCreated")]
[HarmonyPostfix]
private static void OnLobbyCreatedPatch(ref LobbyCreated_t param)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)param.m_eResult == 1)
{
GlobalSaveHelper.SteamLobbyId.Value = param.m_ulSteamIDLobby;
SteamAccountManager.ResetSpoofAccountsInUse();
}
}
[HarmonyPatch("OnLobbyChat")]
[HarmonyPrefix]
private static bool OnLobbyChatPatch(ref LobbyChatMsg_t param)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (!SteamAccountManager.IsUsingSpoofAccount && param.m_ulSteamIDUser == SteamUser.GetSteamID().m_SteamID)
{
param.m_ulSteamIDUser = SteamAccountManager.SpoofAccount.SteamId;
}
return true;
}
}
[HarmonyPatch(typeof(SteamManager))]
internal static class SteamManagerPatch
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
[HarmonyPriority(800)]
private static void AwakePatch()
{
SteamAccountManager.Initialize();
}
}
}
namespace com.quackandcheese.LocalMultiplayer.Objects
{
internal class JsonSave : IDisposable
{
private JObject _data;
private readonly Mutex _mutex;
private const int _mutexTimeoutMs = 5000;
private bool _disposed;
public string DirectoryPath { get; private set; }
public string FileName { get; private set; }
public string FilePath => Path.Combine(DirectoryPath, FileName);
public JsonSave(string directoryPath, string fileName)
{
DirectoryPath = directoryPath;
FileName = fileName;
string name = "Global\\JsonSave_" + fileName.Replace(Path.DirectorySeparatorChar, '_');
_mutex = new Mutex(initiallyOwned: false, name);
RefreshData();
Application.quitting += Dispose;
}
public bool KeyExists(string key)
{
RefreshData();
JObject data = _data;
if (data == null)
{
return false;
}
return data.ContainsKey(key);
}
public T Load<T>(string key, T defaultValue = default(T))
{
if (!TryLoad<T>(key, out var value))
{
return defaultValue;
}
return value;
}
public bool TryLoad<T>(string key, out T value)
{
value = default(T);
RefreshData();
if (_data == null)
{
Plugin.Log.LogError((object)("TryLoad: Data is null. Key: " + key));
return false;
}
JToken val = default(JToken);
if (_data.TryGetValue(key, ref val))
{
try
{
value = val.ToObject<T>();
return true;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("TryLoad: Failed to deserialize key '" + key + "'. " + ex.Message));
}
}
return false;
}
public bool Save<T>(string key, T value)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
bool flag = false;
try
{
flag = _mutex.WaitOne(5000);
if (!flag)
{
Plugin.Log.LogWarning((object)"Save: Could not acquire mutex.");
return false;
}
RefreshData();
if (_data == null)
{
_data = new JObject();
}
_data[key] = JToken.FromObject((object)value);
return WriteFile(_data);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Save: Error saving key '" + key + "'. " + ex.Message));
return false;
}
finally
{
if (flag)
{
_mutex.ReleaseMutex();
}
}
}
private JObject ReadFile()
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
try
{
if (!File.Exists(FilePath))
{
Plugin.Log.LogWarning((object)("ReadFile: Save file not found at \"" + FilePath + "\". Creating new."));
return new JObject();
}
using FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
return JObject.Parse(streamReader.ReadToEnd());
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("ReadFile: Failed to read file \"" + FilePath + "\". " + ex.Message));
return new JObject();
}
}
private bool WriteFile(JObject data)
{
try
{
if (!Directory.Exists(DirectoryPath))
{
Directory.CreateDirectory(DirectoryPath);
}
File.WriteAllText(FilePath, ((object)data).ToString(), Encoding.UTF8);
return true;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("WriteFile: Failed to write file \"" + FilePath + "\". " + ex.Message));
return false;
}
}
private void RefreshData()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
_data = ReadFile();
if (_data == null)
{
Plugin.Log.LogError((object)"RefreshData: Data is null. Creating new.");
_data = new JObject();
}
}
public void Dispose()
{
if (!_disposed)
{
_mutex?.Dispose();
_disposed = true;
}
}
}
internal class JsonSaveValue<T>
{
public JsonSave JsonSave { get; private set; }
public string Key { get; private set; }
public T DefaultValue { get; private set; }
public T Value
{
get
{
return Load();
}
set
{
Save(value);
}
}
public bool HasValue
{
get
{
T value;
return TryLoad(out value);
}
}
public JsonSaveValue(JsonSave jsonSave, string key, T defaultValue = default(T))
{
JsonSave = jsonSave;
Key = key;
DefaultValue = defaultValue;
base..ctor();
}
public T Load()
{
return JsonSave.Load(Key, DefaultValue);
}
public bool TryLoad(out T value)
{
return JsonSave.TryLoad<T>(Key, out value);
}
public void Save(T value)
{
JsonSave.Save(Key, value);
}
}
public struct SteamAccount : IEquatable<SteamAccount>
{
public string Username;
public ulong SteamId;
public SteamAccount(string username, ulong steamId)
{
Username = username;
SteamId = steamId;
}
public bool Equals(SteamAccount other)
{
return SteamId == other.SteamId;
}
public override bool Equals(object obj)
{
if (obj is SteamAccount other)
{
return Equals(other);
}
return false;
}
public static bool operator ==(SteamAccount a, SteamAccount b)
{
return a.Equals(b);
}
public static bool operator !=(SteamAccount a, SteamAccount b)
{
return !a.Equals(b);
}
public override int GetHashCode()
{
return SteamId.GetHashCode();
}
}
}
namespace com.quackandcheese.LocalMultiplayer.Helpers
{
internal static class GlobalSaveHelper
{
public static JsonSave JsonSave { get; private set; }
public static JsonSaveValue<ulong> SteamLobbyId { get; private set; }
public static JsonSaveValue<List<SteamAccount>> SpoofSteamAccounts { get; private set; }
public static JsonSaveValue<List<SteamAccount>> SpoofSteamAccountsInUse { get; private set; }
static GlobalSaveHelper()
{
JsonSave = new JsonSave(Utils.GetPluginPersistentDataPath(), "GlobalSave");
SteamLobbyId = new JsonSaveValue<ulong>(JsonSave, "SteamLobbyId", 0uL);
SpoofSteamAccounts = new JsonSaveValue<List<SteamAccount>>(JsonSave, "SpoofSteamAccounts", new List<SteamAccount>());
SpoofSteamAccountsInUse = new JsonSaveValue<List<SteamAccount>>(JsonSave, "SpoofSteamAccountsInUse", new List<SteamAccount>());
}
public static bool KeyExists(string key)
{
return JsonSave.KeyExists(key);
}
public static T Load<T>(string key, T defaultValue = default(T))
{
return JsonSave.Load(key, defaultValue);
}
public static bool TryLoad<T>(string key, out T value)
{
return JsonSave.TryLoad<T>(key, out value);
}
public static bool Save<T>(string key, T value)
{
return JsonSave.Save(key, value);
}
}
internal static class PhotonNetworkHelper
{
public static void SetPhotonServerSettings()
{
AppSettings appSettings = PhotonNetwork.PhotonServerSettings.AppSettings;
appSettings.AppIdRealtime = ConfigManager.Photon_AppIdRealtime.Value;
appSettings.AppIdVoice = ConfigManager.Photon_AppIdVoice.Value;
}
}
internal static class SteamHelper
{
public static ulong GenerateRandomSteamId()
{
ulong num = 76561197960265728uL;
Random random = new Random();
uint num2 = (uint)random.Next(0, int.MaxValue);
num2 += (uint)random.Next(0, int.MaxValue);
return num + num2;
}
}
}
namespace com.quackandcheese.LocalMultiplayer.Extensions
{
internal static class StringExtensions
{
public static ulong ToUlong(this string value)
{
if (ulong.TryParse(value, out var result))
{
return result;
}
return 0uL;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}