Decompiled source of LocalMultiplayer v1.0.0

plugins/com.quackandcheese.LocalMultiplayer.dll

Decompiled a week ago
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 Photon.Pun;
using Photon.Realtime;
using Steamworks;
using UnityEngine;
using Zorro.Core;
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.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[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.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+261a6f2fb674ae4291be3a56501e76c654468f2e")]
[assembly: AssemblyProduct("com.quackandcheese.LocalMultiplayer")]
[assembly: AssemblyTitle("LocalMultiplayer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 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.0")]
	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.0";

		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("Initialize")]
		[HarmonyPostfix]
		private static void InitializePatch()
		{
			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("LoadUserID")]
		[HarmonyPrefix]
		private static bool LoadUserIDPatch(ref AuthenticationValues __result)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			__result = new AuthenticationValues(Guid.NewGuid().ToString());
			return false;
		}
	}
	[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(typeof(SteamAuthTicketService))]
	internal static class SteamAuthTicketServicePatch
	{
		[HarmonyPatch("GenerateNewTicket")]
		[HarmonyPostfix]
		private static void GenerateNewTicketPatch()
		{
			if (!IsValidClient())
			{
				Application.Quit();
			}
		}

		private static bool IsValidClient()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			Optionable<GeneratedTicket> currentTicket = GameHandler.GetService<SteamAuthTicketService>().CurrentTicket;
			if (!currentTicket.IsSome)
			{
				return false;
			}
			GeneratedTicket value = currentTicket.Value;
			byte[] array = HexStringToByteArray(((GeneratedTicket)(ref value)).TicketData);
			value = currentTicket.Value;
			EBeginAuthSessionResult val = SteamUser.BeginAuthSession(array, ((GeneratedTicket)(ref value)).TicketData.Length, SteamUser.GetSteamID());
			return (int)val == 0;
		}

		public static byte[] HexStringToByteArray(string hex)
		{
			if (hex.Length % 2 != 0)
			{
				throw new ArgumentException("Invalid length for a hex string.");
			}
			byte[] array = new byte[hex.Length / 2];
			for (int i = 0; i < array.Length; i++)
			{
				string value = hex.Substring(i * 2, 2);
				array[i] = Convert.ToByte(value, 16);
			}
			return array;
		}
	}
	[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)
		{
		}
	}
}