Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LocalMultiplayer v1.4.0
com.github.zehsteam.LocalMultiplayer.dll
Decompiled 5 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; 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 Steamworks.Data; using UnityEngine; using com.github.zehsteam.LocalMultiplayer.Helpers; using com.github.zehsteam.LocalMultiplayer.Managers; using com.github.zehsteam.LocalMultiplayer.Objects; using com.github.zehsteam.LocalMultiplayer.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Zehs")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2025 Zehs")] [assembly: AssemblyDescription("Play multiplayer locally with one Steam account.")] [assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyInformationalVersion("1.4.0+2fc33d1437fa32420b85bdfa18c77259be0f0931")] [assembly: AssemblyProduct("LocalMultiplayer")] [assembly: AssemblyTitle("com.github.zehsteam.LocalMultiplayer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.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."); } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data, bool extended = false) { Log((LogLevel)32, data, extended); } public static void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } public static void LogMessage(object data, bool extended = false) { Log((LogLevel)8, data, extended); } public static void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } public static void LogError(object data, bool extended = false) { Log((LogLevel)2, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!extended || IsExtendedLoggingEnabled()) { ManualLogSource manualLogSource = ManualLogSource; if (manualLogSource != null) { manualLogSource.Log(logLevel, data); } } } public static bool IsExtendedLoggingEnabled() { if (ConfigManager.ExtendedLogging == null) { return false; } return ConfigManager.ExtendedLogging.Value; } } [BepInPlugin("com.github.zehsteam.LocalMultiplayer", "LocalMultiplayer", "1.4.0")] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.LocalMultiplayer"); public static Plugin Instance { get; private set; } public ConfigFile Config { get; private set; } public static JsonSave GlobalSave { get; private set; } private void Awake() { Instance = this; Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.LocalMultiplayer")); Logger.LogInfo("LocalMultiplayer has awoken!"); Config = Utils.CreateGlobalConfigFile((BaseUnityPlugin)(object)this); GlobalSave = new JsonSave(Utils.GetPluginPersistentDataPath(), "GlobalSave"); _harmony.PatchAll(typeof(SteamClientPatch)); _harmony.PatchAll(typeof(DataDirectorPatch)); _harmony.PatchAll(typeof(NetworkManagerPatch)); _harmony.PatchAll(typeof(SteamManagerPatch)); _harmony.PatchAll(typeof(InputManagerPatch)); _harmony.PatchAll(typeof(MenuPageMainPatch)); _harmony.PatchAll(typeof(PlayerAvatarPatch)); ConfigManager.Initialize(Config); } } internal static class Utils { public static string GetPluginPersistentDataPath() { return Path.Combine(Application.persistentDataPath, "LocalMultiplayer"); } 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); } public static string GetCurrentStackTrace(int skipFrames = 0, bool includeFileInfo = true) { StackTrace stackTrace = new StackTrace(skipFrames + 1, includeFileInfo); return stackTrace.ToString(); } public static string GetCallStackMethods(int skipFrames = 1) { StackTrace stackTrace = new StackTrace(skipFrames, fNeedFileInfo: false); StackFrame[] frames = stackTrace.GetFrames(); if (frames == null || frames.Length == 0) { return "No stack trace available."; } StringBuilder stringBuilder = new StringBuilder(); int num = 1; StackFrame[] array = frames; foreach (StackFrame stackFrame in array) { MethodBase method = stackFrame.GetMethod(); if (!(method == null)) { string name = method.Name; string arg = ((method.DeclaringType != null) ? method.DeclaringType.FullName : "<UnknownType>"); stringBuilder.AppendLine($"{num}: {arg}.{name}()"); num++; } } return stringBuilder.ToString(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.LocalMultiplayer"; public const string PLUGIN_NAME = "LocalMultiplayer"; public const string PLUGIN_VERSION = "1.4.0"; } } namespace com.github.zehsteam.LocalMultiplayer.Patches { [HarmonyPatch(typeof(DataDirector))] internal static class DataDirectorPatch { [HarmonyPatch("PhotonSetAppId")] [HarmonyPostfix] private static void PhotonSetAppIdPatch() { AppSettings appSettings = PhotonNetwork.PhotonServerSettings.AppSettings; appSettings.AppIdRealtime = ConfigManager.Photon_AppIdRealtime.Value; appSettings.AppIdVoice = ConfigManager.Photon_AppIdVoice.Value; } [HarmonyPatch("SaveSettings")] [HarmonyPrefix] private static bool SaveSettingsPatch() { if (!SteamAccountManager.IsUsingSpoofAccount) { return true; } return false; } [HarmonyPatch("ColorSetBody")] [HarmonyPrefix] private static bool ColorSetBodyPatch(int colorID) { if (!SteamAccountManager.IsUsingSpoofAccount) { return true; } SteamAccountManager.SetCurrentSpoofAccountColor(colorID); return false; } [HarmonyPatch("ColorGetBody")] [HarmonyPrefix] private static bool ColorGetBodyPatch(ref int __result) { if (!SteamAccountManager.IsUsingSpoofAccount) { return true; } __result = SteamAccountManager.SpoofAccount.ColorId; return false; } } [HarmonyPatch(typeof(InputManager))] internal static class InputManagerPatch { [HarmonyPatch("SaveDefaultKeyBindings")] [HarmonyPrefix] private static bool SaveDefaultKeyBindingsPatch() { return !SteamAccountManager.IsUsingSpoofAccount; } [HarmonyPatch("SaveCurrentKeyBindings")] [HarmonyPrefix] private static bool SaveCurrentKeyBindingsPatch() { return !SteamAccountManager.IsUsingSpoofAccount; } } [HarmonyPatch(typeof(MenuPageMain))] internal static class MenuPageMainPatch { [HarmonyPatch("ButtonEventJoinGame")] [HarmonyPrefix] private static bool ButtonEventJoinGamePatch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) SteamAccountManager.AssignSpoofAccount(); SteamManager instance = SteamManager.instance; if (instance != null) { instance.OnGameLobbyJoinRequested(new Lobby(SteamId.op_Implicit(GlobalSaveHelper.SteamLobbyId.Value)), SteamClient.SteamId); } return false; } } [HarmonyPatch(typeof(NetworkManager))] internal static class NetworkManagerPatch { [HarmonyPatch("OnDisconnected")] [HarmonyPostfix] private static void OnDisconnectedPatch() { SteamAccountManager.UnassignSpoofAccount(); } } [HarmonyPatch(typeof(PlayerAvatar))] internal static class PlayerAvatarPatch { [HarmonyPatch("AddToStatsManager")] [HarmonyPrefix] private static void AddToStatsManagerPatch() { PhotonNetwork.NickName = SteamClient.Name; } } [HarmonyPatch(typeof(SteamClient))] internal static class SteamClientPatch { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool NamePatch(ref string __result) { if (!SteamAccountManager.IsUsingSpoofAccount) { return true; } __result = SteamAccountManager.SpoofAccount.Username; return false; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool SteamIdPatch(ref SteamId __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 = SteamId.op_Implicit(SteamAccountManager.SpoofAccount.SteamId); return false; } } [HarmonyPatch(typeof(SteamManager))] internal static class SteamManagerPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] [HarmonyPriority(800)] private static void AwakePatch() { SteamAccountManager.Initialize(); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { if (!SteamHelper.IsValidClient()) { Application.Quit(); } } [HarmonyPatch("OnLobbyCreated")] [HarmonyPostfix] private static void OnLobbyCreatedPatch(ref Result _result, ref Lobby _lobby) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((int)_result == 1) { GlobalSaveHelper.SteamLobbyId.Value = SteamId.op_Implicit(((Lobby)(ref _lobby)).Id); SteamAccountManager.ResetSpoofAccountsInUse(); } } [HarmonyPatch("SendSteamAuthTicket")] [HarmonyPrefix] private static bool SendSteamAuthTicketPatch() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown PhotonNetwork.AuthValues = new AuthenticationValues(Guid.NewGuid().ToString()); return false; } } } namespace com.github.zehsteam.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) { Logger.LogError("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) { Logger.LogError("TryLoad: Failed to deserialize key '" + key + "'. " + ex.Message); } } return false; } public bool Save<T>(string key, T value) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown bool flag = false; try { flag = _mutex.WaitOne(5000); if (!flag) { Logger.LogWarning("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) { Logger.LogError("Save: Error saving key '" + key + "'. " + ex.Message); return false; } finally { if (flag) { _mutex.ReleaseMutex(); } } } private JObject ReadFile() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown try { if (!File.Exists(FilePath)) { Logger.LogWarning("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) { Logger.LogError("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) { Logger.LogError("WriteFile: Failed to write file \"" + FilePath + "\". " + ex.Message); return false; } } private void RefreshData() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown _data = ReadFile(); if (_data == null) { Logger.LogError("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 int ColorId; public SteamAccount(string username, ulong steamId) { ColorId = 0; Username = username; SteamId = steamId; } public SteamAccount(string username, ulong steamId, int colorIndex) : this(username, steamId) { ColorId = colorIndex; } 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.github.zehsteam.LocalMultiplayer.Managers { 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(SteamClient.Name, SteamId.op_Implicit(SteamClient.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() { Logger.LogInfo($"SteamAccountManager: AssignSpoofAccount(); IsUsingSpoofAccount: {IsUsingSpoofAccount}"); if (!IsUsingSpoofAccount) { SteamAccount availableSpoofAccount = GetAvailableSpoofAccount(); AddSpoofAccountInUse(availableSpoofAccount); SpoofAccount = availableSpoofAccount; PhotonNetwork.NickName = availableSpoofAccount.Username; Logger.LogInfo($"SteamAccountManager: Set spoof account (Username: \"{availableSpoofAccount.Username}\", SteamID: {availableSpoofAccount.SteamId})"); } } public static void UnassignSpoofAccount() { Logger.LogInfo($"SteamAccountManager: UnassignSpoofAccount(); IsUsingSpoofAccount: {IsUsingSpoofAccount}"); if (IsUsingSpoofAccount) { RemoveSpoofAccountInUse(SpoofAccount); SpoofAccount = default(SteamAccount); PhotonNetwork.NickName = RealAccount.Username; Logger.LogInfo("SteamAccountManager: UnassignSpoofAccount(); Unassigned spoof account."); } } 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; } public static void SetCurrentSpoofAccountColor(int id) { if (IsUsingSpoofAccount) { SpoofAccount.ColorId = id; UpdateCurrentSpoofAccountData(); } } 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) { Logger.LogWarning("SteamAccountManager: 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 accountToAdd) { List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccountsInUse.Value; if (!value.Contains(accountToAdd)) { value.Add(accountToAdd); GlobalSaveHelper.SpoofSteamAccountsInUse.Value = value; } } private static void RemoveSpoofAccountInUse(SteamAccount accountToRemove) { List<SteamAccount> value = GlobalSaveHelper.SpoofSteamAccountsInUse.Value; GlobalSaveHelper.SpoofSteamAccountsInUse.Value = value.Where((SteamAccount x) => x.SteamId != accountToRemove.SteamId).ToList(); } } } namespace com.github.zehsteam.LocalMultiplayer.Helpers { internal static class GlobalSaveHelper { public static JsonSave JsonSave => Plugin.GlobalSave; 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() { 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>()); } } 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; } public static bool IsValidClient() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (SteamClient.Name == "IGGGAMES") { return false; } if (SteamId.op_Implicit(SteamClient.SteamId) == 12345678) { return false; } if (AppId.op_Implicit(SteamClient.AppId) == 480) { return false; } AuthTicket steamAuthTicket = SteamManager.instance.steamAuthTicket; if (steamAuthTicket == null) { return false; } BeginAuthResult val = SteamUser.BeginAuthSession(steamAuthTicket.Data, SteamClient.SteamId); return (int)val == 0; } } } namespace com.github.zehsteam.LocalMultiplayer.Extensions { internal static class StringExtensions { public static ulong ToUlong(this string value, ulong defaultValue = 0uL) { if (!ulong.TryParse(value, out var result)) { return defaultValue; } return result; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }