Decompiled source of MultiplayerUtil v1.5.4

MultiplayerUtil.dll

Decompiled 2 months ago
using System;
using System.Collections;
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.Tasks;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MultiplayerUtil.Client;
using MultiplayerUtil.Server;
using Newtonsoft.Json;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("MultiplayerUtil")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MultiplayerUtil")]
[assembly: AssemblyTitle("MultiplayerUtil")]
[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 MultiplayerUtil
{
	[BepInPlugin("DolfeLive.Modding.MultiplayerUtil", "DolfeMultiplayersUtil", "1.0.0")]
	public class _MultiplayerUtil : BaseUnityPlugin
	{
		public static string modName = "MultiplayerUtil";

		public static _MultiplayerUtil instance;

		public static bool cracked = false;

		private GameObject smObj;

		public static uint appId
		{
			get
			{
				if (!cracked)
				{
					return 1229490u;
				}
				return 480u;
			}
		}

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			instance = this;
			Semtings.Init();
			new Harmony("DolfeLive.Modding.MultiplayerUtil").PatchAll();
			SceneManager.sceneLoaded += delegate
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				if (SceneHelper.CurrentScene == "Main Menu" && !((Object)(object)smObj != (Object)null))
				{
					smObj = new GameObject("SteamManagerUtil");
					smObj.AddComponent<SteamManager>();
					Object.DontDestroyOnLoad((Object)(object)smObj);
				}
			};
		}

		private void Update()
		{
			SteamClient.RunCallbacks();
		}
	}
	public static class Data
	{
		public static T Deserialize<T>(byte[] serializedData)
		{
			if (serializedData == null || serializedData.Length == 0)
			{
				Logger.LogError("Failed to deserialize data: Empty or null data received");
				throw new ArgumentException("Serialized data cannot be null or empty.", "serializedData");
			}
			try
			{
				return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(serializedData));
			}
			catch (Exception ex)
			{
				Logger.LogError($"Failed to deserialize data: {ex.Message}, Data: {serializedData}");
				throw;
			}
		}

		public static bool TryDeserialize<T>(byte[] serializedData, out T result)
		{
			if (serializedData == null || serializedData.Length == 0)
			{
				Logger.LogError("Failed to deserialize data: Empty or null data received");
				throw new ArgumentException("Serialized data cannot be null or empty.", "serializedData");
			}
			try
			{
				string @string = Encoding.UTF8.GetString(serializedData);
				result = JsonConvert.DeserializeObject<T>(@string);
				return true;
			}
			catch (Exception)
			{
			}
			result = default(T);
			return false;
		}

		public static byte[] Serialize(object data)
		{
			if (data == null)
			{
				Logger.LogError("Failed to serialize data: Null object provided");
				throw new ArgumentNullException("data");
			}
			try
			{
				string s = JsonConvert.SerializeObject(data);
				return Encoding.UTF8.GetBytes(s);
			}
			catch (Exception ex)
			{
				Logger.LogError("Failed to serialize data: " + ex.Message);
				throw;
			}
		}

		public static P2PSend ConvertSendMethodToP2PSend(SendMethod method)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_000b: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			P2PSend val = (P2PSend)0;
			if ((method & SendMethod.Reliable) == SendMethod.Reliable)
			{
				val = (P2PSend)(val | 2);
			}
			if ((method & SendMethod.Unreliable) == 0)
			{
				val = (P2PSend)(val | 0);
			}
			if ((method & SendMethod.UnreliableNoDelay) == SendMethod.UnreliableNoDelay)
			{
				val = (P2PSend)(val | 1);
			}
			if ((method & SendMethod.ReliableWithBuffering) == SendMethod.ReliableWithBuffering)
			{
				val = (P2PSend)(val | 3);
			}
			return val;
		}

		public static SendMethod ConvertP2PSendToSendMethod(P2PSend p2pSend)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			SendMethod sendMethod = SendMethod.Unreliable;
			if ((p2pSend & 2) == 2)
			{
				sendMethod |= SendMethod.Reliable;
			}
			if ((p2pSend & 0) == 0)
			{
				sendMethod |= SendMethod.Unreliable;
			}
			if ((p2pSend & 1) == 1)
			{
				sendMethod |= SendMethod.UnreliableNoDelay;
			}
			if ((p2pSend & 3) == 3)
			{
				sendMethod |= SendMethod.ReliableWithBuffering;
			}
			return sendMethod;
		}

		public static byte boolsToBinary(bool[] bools)
		{
			byte b = 0;
			int num = Math.Min(bools.Length, 8);
			for (int i = 0; i < num; i++)
			{
				if (bools[i])
				{
					b |= (byte)(1 << i);
				}
			}
			return b;
		}

		public static bool[] byteToBools(byte data)
		{
			bool[] array = new bool[8];
			for (int i = 0; i < 8; i++)
			{
				array[i] = (data & (1 << i)) != 0;
			}
			return array;
		}
	}
	public static class LobbyManager
	{
		public static bool extraLogging;

		public static bool isLobbyOwner => SteamManager.instance.isLobbyOwner;

		public static Lobby? current_lobby => SteamManager.instance.current_lobby;

		public static SteamId selfID => SteamManager.instance.selfID;

		public static float importantUpdatesASec => 33.3f;

		public static float unimportantUpdatesAMin => 12f;

		public static void restartLoop()
		{
			if (SteamManager.instance.dataLoop != null)
			{
				((MonoBehaviour)SteamManager.instance).StopCoroutine(SteamManager.instance.dataLoop);
				SteamManager.instance.dataLoop = ((MonoBehaviour)SteamManager.instance).StartCoroutine(SteamManager.instance.DataLoopInit());
			}
		}

		public static void CreateLobby(string lobbyName, int? maxPlayers, bool publicLobby, bool cracked, bool mods, (string, string) modIdentifier)
		{
			Logger.Log("Creating Lobby");
			SteamManager.instance.HostLobby(lobbyName, maxPlayers, publicLobby, cracked, mods, modIdentifier);
		}

		public static async Task<List<Lobby>> FetchLobbies((string, string) modIdentifierKVP)
		{
			List<Lobby> foundLobbies = new List<Lobby>();
			try
			{
				LobbyQuery lobbyList = SteamMatchmaking.LobbyList;
				Lobby[] array = await ((LobbyQuery)(ref lobbyList)).RequestAsync();
				if (array != null)
				{
					foundLobbies = array.Where((Lobby lobby) => ((Lobby)(ref lobby)).Data.Any((KeyValuePair<string, string> data) => data.Key == modIdentifierKVP.Item1 && data.Value == modIdentifierKVP.Item2) && !SteamManager.BannedLobbies.Contains(((Lobby)(ref lobby)).Id)).ToList();
				}
			}
			catch (Exception arg)
			{
				Logger.LogError($"Lobby finding exeption: {arg}");
			}
			Logger.Log($"Found Lobbies: {foundLobbies.Count}");
			return foundLobbies;
		}

		public static void JoinLobbyWithID(ulong id)
		{
			Logger.Log("Joining Lobby");
			SteamManager.instance.JoinLobbyWithID(id);
		}

		public static void SendMessage(string msg)
		{
			SteamManager.instance.SendChatMessage(msg);
		}

		public static void SendData(object data, SendMethod sendMethod = SendMethod.Reliable)
		{
			SteamManager.instance.DataSend(data, sendMethod);
		}

		public static void SendToLobbyOwner(object data, SendMethod sendMethod = SendMethod.Reliable)
		{
			SteamManager.instance.LobbyOwnerSend(data, sendMethod);
		}

		public static void InviteFriend()
		{
			SteamManager.instance.InviteFriend();
		}

		public static void Disconnect()
		{
			SteamManager.instance.Disconnect();
		}

		public static void ReInnitSteamClient(bool cracked)
		{
			SteamManager.instance.ReInit(cracked);
		}

		public static void AddToBannedUsers(SteamId steamId)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SteamManager.instance.BannedSteamIds.Add(steamId);
		}

		public static void AddToBlockedUsers(SteamId steamId)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SteamManager.instance.BlockedSteamIds.Add(steamId);
		}

		public static void RemoveFromBannedUsers(SteamId steamId)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SteamManager.instance.BannedSteamIds.Remove(steamId);
		}

		public static void RemoveFromBlockedUsers(SteamId steamId)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SteamManager.instance.BlockedSteamIds.Remove(steamId);
		}

		public static void ClearBannedUsers()
		{
			SteamManager.instance.BannedSteamIds.Clear();
		}

		public static void ClearBlockedUsers()
		{
			SteamManager.instance.BlockedSteamIds.Clear();
		}

		public static void BanUserFromLobby(SteamId steamId)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (isLobbyOwner)
			{
				SendData(new AuthoritativePacket
				{
					type = AuthoritativeTypes.Banned,
					id = steamId
				});
			}
		}

		public static void KickUserFromLobby(SteamId steamId)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (isLobbyOwner)
			{
				SendData(new AuthoritativePacket
				{
					type = AuthoritativeTypes.Kicked,
					id = steamId
				});
			}
		}
	}
	public static class Logger
	{
		private enum EType
		{
			None,
			Client,
			Server
		}

		private enum ELogType
		{
			Normal,
			Warning,
			Error
		}

		public static void ExtraLog(string message)
		{
			if (LobbyManager.extraLogging)
			{
				Log(message, EType.None);
			}
		}

		public static void Log(string message)
		{
			Log(message, EType.None);
		}

		public static void LogWarning(string message)
		{
			Log(message, EType.None, ELogType.Warning);
		}

		public static void LogError(string message)
		{
			Log(message, EType.None, ELogType.Error);
		}

		public static void Log(string message, bool Client)
		{
			Log(message, Client ? EType.Client : EType.Server);
		}

		public static void LogWarning(string message, bool Client)
		{
			Log(message, Client ? EType.Client : EType.Server, ELogType.Warning);
		}

		public static void LogError(string message, bool Client)
		{
			Log(message, Client ? EType.Client : EType.Server, ELogType.Error);
		}

		public static void UselessLog(string message)
		{
		}

		public static void StackTraceLog(object msg, int offset = 0)
		{
			LogError(msg.ToString());
		}

		private static void Log(string message, EType etype, ELogType eLogType = ELogType.Normal)
		{
			string callingNamespace = GetCallingNamespace();
			string text = "[" + GetModName() + "] [" + callingNamespace + "]" + etype switch
			{
				EType.None => "", 
				EType.Client => " [Client]", 
				_ => " [Server]", 
			} + " " + message;
			switch (eLogType)
			{
			case ELogType.Normal:
				Debug.Log((object)text);
				break;
			case ELogType.Warning:
				Debug.LogWarning((object)text);
				break;
			case ELogType.Error:
				Debug.LogError((object)text);
				break;
			}
		}

		private static string GetCallingNamespace()
		{
			StackTrace stackTrace = new StackTrace();
			for (int i = 3; i < stackTrace.FrameCount; i++)
			{
				MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
				if (methodBase != null && methodBase.DeclaringType != null)
				{
					return methodBase.DeclaringType.Namespace ?? "UnknownNamespace";
				}
			}
			return "UnknownNamespace";
		}

		private static string GetModName()
		{
			return Assembly.GetCallingAssembly().GetName().Name ?? "UnknownMod";
		}
	}
	public class SteamManager : MonoBehaviour
	{
		public static SteamManager instance;

		public const float importantUpdatesASec = 33.3f;

		public const float unimportantUpdatesAMin = 12f;

		public static string p2pEstablishMessage = "IWouldLikeToEstablishP2P!";

		public Lobby? current_lobby;

		public List<SteamId> BannedSteamIds = new List<SteamId>();

		public List<SteamId> BlockedSteamIds = new List<SteamId>();

		public static List<SteamId?> BannedLobbies = new List<SteamId?>();

		public SteamId selfID;

		private string playerName;

		public bool isLobbyOwner;

		private string LobbyName;

		private int maxPlayers;

		private bool publicLobby;

		private bool cracked;

		public Coroutine? dataLoop;

		public Serveier server;

		private MultiplayerUtil.Client.Client client;

		private bool CheckForP2P;

		public static bool SelfP2PSafeguards = true;

		public const int channelToUse = 0;

		private void Awake()
		{
			//IL_0056: 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)
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			instance = this;
			UnityEvent startupComplete = Callbacks.StartupComplete;
			if (startupComplete != null)
			{
				startupComplete.Invoke();
			}
			((UnityEvent<(byte[], SteamId?)>)(object)Callbacks.p2pMessageReceived).AddListener((UnityAction<(byte[], SteamId?)>)delegate((byte[], SteamId?) _)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: 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_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				var (array, sender) = _;
				if (array != null)
				{
					SteamId value = sender.Value;
					if (((SteamId)(ref value)).IsValid)
					{
						if (SelfP2PSafeguards && (!sender.HasValue || SteamId.op_Implicit(sender.Value) == SteamId.op_Implicit(LobbyManager.selfID)))
						{
							string[] obj = new string[6]
							{
								"Failed at reciving, why: ",
								sender.HasValue ? "Has value" : "Does not have value",
								" ",
								(array.Length != 0) ? string.Join("", array) : "",
								", Sender: ",
								null
							};
							object obj2;
							if (!sender.HasValue)
							{
								obj2 = "null";
							}
							else
							{
								value = sender.Value;
								obj2 = ((object)(SteamId)(ref value)).ToString();
							}
							obj[5] = (string)obj2;
							Debug.Log((object)string.Concat(obj));
						}
						else
						{
							ObserveManager.OnMessageRecived(array, sender);
						}
						return;
					}
				}
				Debug.LogError((object)$"Received invalid P2P message: data or sender is null. data:{array == null}, Sender:{sender.Value}");
			});
			Debug.unityLogger.filterLogType = (LogType)7;
			selfID = SteamClient.SteamId;
			SetupCallbacks();
		}

		public void ReInit(bool cracked)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (cracked != this.cracked)
			{
				this.cracked = cracked;
				SteamClient.Shutdown();
				SteamClient.Init(_MultiplayerUtil.appId, true);
				selfID = SteamClient.SteamId;
			}
		}

		private void SetupCallbacks()
		{
			Dispatch.OnException = delegate(Exception e)
			{
				Logger.LogError("Exception: " + e.Message + ", " + e.StackTrace);
			};
			SteamUtils.OnSteamShutdown += delegate
			{
				Callbacks.OnSteamShutdown();
			};
			SteamMatchmaking.OnLobbyCreated += delegate(Result result, Lobby lobby)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				Logger.ExtraLog($"Lobby Created, result: {result}, lobby: {((Lobby)(ref lobby)).Id}");
				Callbacks.OnLobbyCreated.Invoke(lobby);
			};
			SteamNetworking.OnP2PSessionRequest = (Action<SteamId>)Delegate.Combine(SteamNetworking.OnP2PSessionRequest, (Action<SteamId>)delegate(SteamId id)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: 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_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: 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_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				Logger.ExtraLog($"P2P requested from: {id}");
				if (!SelfP2PSafeguards || SteamId.op_Implicit(id) != SteamId.op_Implicit(selfID))
				{
					if (BannedSteamIds.Contains(id))
					{
						Logger.ExtraLog($"P2P request from banned user: {id}");
					}
					else if (client.connectedPeers.Contains(id))
					{
						Logger.ExtraLog($"P2P request from already connected user: {id}");
					}
					else if (SteamNetworking.AcceptP2PSessionWithUser(id))
					{
						Logger.Log($"P2P session accepted with: {id}");
						if (isLobbyOwner)
						{
							server.besties.Add(id);
						}
						else
						{
							client.connectedPeers.Add(id);
						}
					}
					else
					{
						Logger.ExtraLog($"P2P session request failed with: {id}");
					}
				}
			});
			SteamNetworking.OnP2PConnectionFailed = (Action<SteamId, P2PSessionError>)Delegate.Combine(SteamNetworking.OnP2PConnectionFailed, (Action<SteamId, P2PSessionError>)delegate(SteamId id, P2PSessionError sessionError)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				Logger.LogWarning($"P2P Connection failed, id: {id}, error: {sessionError}");
				Callbacks.OnP2PConnectionFailed.Invoke(id, sessionError);
			});
			SteamMatchmaking.OnLobbyMemberJoined += delegate(Lobby l, Friend f)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				Logger.ExtraLog("Lobby member joined: " + ((Friend)(ref f)).Name);
				if (SteamId.op_Implicit(f.Id) != SteamId.op_Implicit(selfID) && !BannedSteamIds.Contains(f.Id))
				{
					bool num2 = EstablishP2P(f);
					if (isLobbyOwner)
					{
						server.besties.Add(f.Id);
					}
					else
					{
						client.connectedPeers.Add(f.Id);
					}
					if (!num2)
					{
						Logger.LogWarning("Falied to establish p2p with: " + ((Friend)(ref f)).Name);
					}
					Callbacks.OnLobbyMemberJoined.Invoke(l, f);
				}
				if (isLobbyOwner)
				{
					BannedSteamIds.Contains(f.Id);
				}
			};
			SteamMatchmaking.OnLobbyEntered += delegate(Lobby l)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				Friend owner = ((Lobby)(ref l)).Owner;
				if (!string.IsNullOrEmpty(((Friend)(ref owner)).Name) && SteamId.op_Implicit(((Lobby)(ref l)).Owner.Id) != SteamId.op_Implicit(selfID))
				{
					owner = ((Lobby)(ref l)).Owner;
					Logger.ExtraLog("Joined Lobby: " + ((Friend)(ref owner)).Name);
					client.Connect(((Lobby)(ref l)).Owner.Id);
					foreach (Friend member in ((Lobby)(ref l)).Members)
					{
						client.connectedPeers.Add(member.Id);
						instance.EstablishP2P(member.Id);
					}
					Callbacks.OnLobbyEntered.Invoke(l);
				}
			};
			SteamMatchmaking.OnChatMessage += delegate(Lobby lo, Friend fr, string st)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: 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_0044: Unknown result type (might be due to invalid IL or missing references)
				if (!BlockedSteamIds.Contains(fr.Id) && !(st == p2pEstablishMessage))
				{
					Logger.Log("Chat message received from " + ((Friend)(ref fr)).Name + ": " + st);
					Callbacks.OnChatMessageReceived.Invoke(lo, fr, st);
				}
			};
			SteamMatchmaking.OnLobbyMemberLeave += delegate(Lobby Lob, Friend Fri)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				if (isLobbyOwner)
				{
					server.besties.Remove(Fri.Id);
					Closep2P(Fri);
				}
				else
				{
					client.connectedPeers.Remove(Fri.Id);
					Closep2P(Fri);
				}
				Callbacks.OnLobbyMemberLeave.Invoke(Fri.Id);
				Logger.ExtraLog("Lobby member left: " + ((Friend)(ref Fri)).Name);
			};
			SteamMatchmaking.OnLobbyMemberDisconnected += delegate(Lobby Lob, Friend Fri)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				if (isLobbyOwner)
				{
					server.besties.Remove(Fri.Id);
					Closep2P(Fri);
				}
				else
				{
					client.connectedPeers.Remove(Fri.Id);
					Closep2P(Fri);
				}
				Callbacks.OnLobbyMemberLeave.Invoke(Fri.Id);
				Logger.ExtraLog("Lobby member disconnected: " + ((Friend)(ref Fri)).Name);
			};
			ObserveManager.SubscribeToType(typeof(AuthoritativePacket), out Callbacks.SenderUnityEvent whenDetected);
			((UnityEvent<(byte[], SteamId?)>)(object)whenDetected).AddListener((UnityAction<(byte[], SteamId?)>)delegate((byte[], SteamId?) _)
			{
				//IL_001e: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_0301: Unknown result type (might be due to invalid IL or missing references)
				//IL_031a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0180: Unknown result type (might be due to invalid IL or missing references)
				//IL_0236: Unknown result type (might be due to invalid IL or missing references)
				//IL_023b: Unknown result type (might be due to invalid IL or missing references)
				//IL_023f: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Unknown result type (might be due to invalid IL or missing references)
				SteamId? item = _.Item2;
				ulong? num = (item.HasValue ? new ulong?(SteamId.op_Implicit(item.GetValueOrDefault())) : null);
				ref Lobby? reference = ref current_lobby;
				SteamId? obj;
				Lobby valueOrDefault;
				if (!reference.HasValue)
				{
					obj = null;
				}
				else
				{
					valueOrDefault = reference.GetValueOrDefault();
					obj = ((Lobby)(ref valueOrDefault)).Owner.Id;
				}
				item = obj;
				if (num == (item.HasValue ? new ulong?(SteamId.op_Implicit(item.GetValueOrDefault())) : null))
				{
					AuthoritativePacket authoritativePacket = Data.Deserialize<AuthoritativePacket>(_.Item1);
					if (SteamId.op_Implicit(authoritativePacket.id) == SteamId.op_Implicit(selfID))
					{
						switch (authoritativePacket.type)
						{
						case AuthoritativeTypes.Kicked:
						{
							ref Lobby? reference5 = ref current_lobby;
							object obj3;
							if (!reference5.HasValue)
							{
								obj3 = null;
							}
							else
							{
								valueOrDefault = reference5.GetValueOrDefault();
								obj3 = ((Lobby)(ref valueOrDefault)).Members;
							}
							foreach (Friend item3 in (IEnumerable<Friend>)obj3)
							{
								Closep2P(item3);
							}
							if (isLobbyOwner)
							{
								server.besties.Clear();
							}
							else
							{
								client.connectedPeers.Clear();
							}
							ref Lobby? reference6 = ref current_lobby;
							if (reference6.HasValue)
							{
								valueOrDefault = reference6.GetValueOrDefault();
								((Lobby)(ref valueOrDefault)).Leave();
							}
							current_lobby = null;
							break;
						}
						case AuthoritativeTypes.Banned:
						{
							ref Lobby? reference2 = ref current_lobby;
							object obj2;
							if (!reference2.HasValue)
							{
								obj2 = null;
							}
							else
							{
								valueOrDefault = reference2.GetValueOrDefault();
								obj2 = ((Lobby)(ref valueOrDefault)).Members;
							}
							foreach (Friend item4 in (IEnumerable<Friend>)obj2)
							{
								Closep2P(item4);
							}
							if (isLobbyOwner)
							{
								server.besties.Clear();
							}
							else
							{
								client.connectedPeers.Clear();
							}
							List<SteamId?> bannedLobbies = BannedLobbies;
							ref Lobby? reference3 = ref current_lobby;
							SteamId? item2;
							if (!reference3.HasValue)
							{
								item2 = null;
							}
							else
							{
								valueOrDefault = reference3.GetValueOrDefault();
								item2 = ((Lobby)(ref valueOrDefault)).Id;
							}
							bannedLobbies.Add(item2);
							ref Lobby? reference4 = ref current_lobby;
							if (reference4.HasValue)
							{
								valueOrDefault = reference4.GetValueOrDefault();
								((Lobby)(ref valueOrDefault)).Leave();
							}
							current_lobby = null;
							break;
						}
						}
					}
					else
					{
						Closep2P(authoritativePacket.id);
						Logger.ExtraLog(string.Format("player {0}: {1}", (authoritativePacket.type == AuthoritativeTypes.Kicked) ? "kicked" : "banned", authoritativePacket.id));
						if (isLobbyOwner)
						{
							server.besties.Remove(authoritativePacket.id);
						}
						else
						{
							client.connectedPeers.Remove(authoritativePacket.id);
						}
						if (authoritativePacket.type == AuthoritativeTypes.Banned)
						{
							Callbacks.OnLobbyMemberBanned.Invoke(authoritativePacket.id);
						}
						else if (authoritativePacket.type == AuthoritativeTypes.Kicked)
						{
							Callbacks.OnLobbyMemberLeave.Invoke(authoritativePacket.id);
						}
					}
				}
			});
		}

		public bool EstablishP2P(dynamic bestie)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			byte[] bytes = Encoding.UTF8.GetBytes(p2pEstablishMessage);
			if (!(bestie is Friend val))
			{
				if (bestie is SteamId val2)
				{
					if (SelfP2PSafeguards && val2.Value == selfID.Value)
					{
						Logger.ExtraLog("Skippng establishing p2p with self");
						return true;
					}
					Logger.Log($"Establishing p2p with: {val2}");
					return SteamNetworking.SendP2PPacket(val2, bytes, -1, 0, (P2PSend)2);
				}
				Logger.LogError("Error with establishing p2p");
				return false;
			}
			if (SelfP2PSafeguards && val.Id.Value == selfID.Value)
			{
				Logger.ExtraLog("Skippng establishing p2p with self");
				return true;
			}
			Logger.Log($"Establishing p2p with: {((Friend)(ref val)).Name}, {val.Id}");
			return SteamNetworking.SendP2PPacket(val.Id, bytes, -1, 0, (P2PSend)2);
		}

		public bool Closep2P(dynamic unbestie)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!(unbestie is Friend val))
			{
				if (unbestie is SteamId val2)
				{
					Logger.StackTraceLog($"DeEstablishing p2p with: {val2}");
					return SteamNetworking.CloseP2PSessionWithUser(val2);
				}
				Logger.LogError("Error with closing p2p");
				return false;
			}
			Logger.StackTraceLog($"DeEstablishing p2p with: {((Friend)(ref val)).Name}, {val.Id}");
			return SteamNetworking.CloseP2PSessionWithUser(val.Id);
		}

		public IEnumerator DataLoopInit()
		{
			if (dataLoop != null)
			{
				Logger.StackTraceLog("Dataloop alr running");
				yield break;
			}
			Logger.ExtraLog("Data Loop Init Activated");
			float interval = 0.03003003f;
			float unimportantInterval = 5f;
			float unimportantTimeElapsed = 0f;
			CheckForP2P = true;
			yield return (object)new WaitForSecondsRealtime(0.1f);
			try
			{
				while (true)
				{
					if (!current_lobby.HasValue)
					{
						yield return (object)new WaitForSeconds(5f);
						if (!current_lobby.HasValue)
						{
							Logger.LogWarning("Breaking out of DataLoopInit");
							yield break;
						}
						MonoBehaviour.print((object)"everything was fine");
					}
					UnityEvent timeToSendImportantData = Callbacks.TimeToSendImportantData;
					if (timeToSendImportantData != null)
					{
						timeToSendImportantData.Invoke();
					}
					if (isLobbyOwner)
					{
						unimportantTimeElapsed += interval;
						if (unimportantTimeElapsed >= unimportantInterval)
						{
							Logger.UselessLog("TimeToSendUnimportantData invoked");
							UnityEvent timeToSendUnimportantData = Callbacks.TimeToSendUnimportantData;
							if (timeToSendUnimportantData != null)
							{
								timeToSendUnimportantData.Invoke();
							}
							ref Lobby? reference = ref current_lobby;
							if (reference.HasValue)
							{
								Lobby valueOrDefault = reference.GetValueOrDefault();
								ref Lobby? reference2 = ref current_lobby;
								int? obj;
								if (!reference2.HasValue)
								{
									obj = null;
								}
								else
								{
									Lobby valueOrDefault2 = reference2.GetValueOrDefault();
									obj = ((Lobby)(ref valueOrDefault2)).Members.Count();
								}
								((Lobby)(ref valueOrDefault)).SetData("members", $"{obj}/{maxPlayers}");
							}
							unimportantTimeElapsed = 0f;
						}
					}
					if (!current_lobby.HasValue)
					{
						break;
					}
					yield return (object)new WaitForSeconds(interval);
				}
				Logger.LogWarning("Breaking out of DataLoopInit");
			}
			finally
			{
				CheckForP2P = false;
				Logger.ExtraLog("DataLoopInit ending");
			}
		}

		public void DataSend(object data, SendMethod sendMethod)
		{
			if (!current_lobby.HasValue)
			{
				return;
			}
			try
			{
				byte[] data2 = Data.Serialize(new NetworkWrapper
				{
					ClassType = data.GetType().AssemblyQualifiedName,
					ClassData = Data.Serialize(data)
				});
				if (isLobbyOwner)
				{
					server.Send(data2, sendMethod);
				}
				else
				{
					client.Send(data2, sendMethod);
				}
			}
			catch (Exception arg)
			{
				Logger.ExtraLog($"Data Send Exception: {arg}");
			}
		}

		public void LobbyOwnerSend(object data, SendMethod sendMethod)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!current_lobby.HasValue)
			{
				return;
			}
			try
			{
				NetworkWrapper data2 = new NetworkWrapper
				{
					ClassType = data.GetType().AssemblyQualifiedName,
					ClassData = Data.Serialize(data)
				};
				Lobby value = current_lobby.Value;
				Friend owner = ((Lobby)(ref value)).Owner;
				byte[] array = Data.Serialize(data2);
				if (SelfP2PSafeguards && SteamId.op_Implicit(owner.Id) == SteamId.op_Implicit(LobbyManager.selfID))
				{
					Logger.UselessLog("Skipping sending p2p to self");
					return;
				}
				P2PSend val = Data.ConvertSendMethodToP2PSend(sendMethod);
				SteamNetworking.SendP2PPacket(owner.Id, array, array.Length, 0, val);
			}
			catch (Exception arg)
			{
				Logger.ExtraLog($"Data Send Exception: {arg}");
			}
		}

		private void Update()
		{
			if (!CheckForP2P)
			{
				return;
			}
			(byte[], SteamId?) tuple = CheckForP2PMessages();
			var (array, val) = tuple;
			if (array == null && !val.HasValue)
			{
				return;
			}
			try
			{
				if (Encoding.Default.GetString(tuple.Item1) == p2pEstablishMessage)
				{
					Logger.ExtraLog("Received P2P intro string message!");
					return;
				}
			}
			catch
			{
			}
			((UnityEvent<(byte[], SteamId?)>)(object)Callbacks.p2pMessageReceived).Invoke(tuple);
		}

		public async void HostLobby(string LobbyName, int? maxPlayers, bool publicLobby, bool cracked, bool mods, (string, string) ModLobbyIDentifiers)
		{
			if (!SteamClient.IsValid)
			{
				Logger.LogWarning("Steam client is not initialized");
				try
				{
					ReInit(_MultiplayerUtil.appId == 480);
					Logger.ExtraLog("Reinited steam");
					return;
				}
				catch (Exception arg)
				{
					Logger.LogError($"STEAM ERROR: {arg}");
					Logger.LogWarning("Try launching steam if it isnt launched!");
					return;
				}
			}
			Lobby valueOrDefault;
			if (current_lobby.HasValue)
			{
				if (isLobbyOwner && server.besties.Count > 0)
				{
					Lobby value = current_lobby.Value;
					Friend owner = ((Lobby)(ref value)).Members.FirstOrDefault((Func<Friend, bool>)((Friend _) => SteamId.op_Implicit(_.Id) == server.besties[0].Value));
					ref Lobby? reference = ref current_lobby;
					if (reference.HasValue)
					{
						valueOrDefault = reference.GetValueOrDefault();
						((Lobby)(ref valueOrDefault)).SetData("Owner", ((Friend)(ref owner)).Name);
					}
					((Lobby)(ref value)).Owner = owner;
				}
				ref Lobby? reference2 = ref current_lobby;
				if (reference2.HasValue)
				{
					valueOrDefault = reference2.GetValueOrDefault();
					((Lobby)(ref valueOrDefault)).SendChatString($":::Leaving.{selfID.Value}");
				}
				ref Lobby? reference3 = ref current_lobby;
				if (reference3.HasValue)
				{
					valueOrDefault = reference3.GetValueOrDefault();
					((Lobby)(ref valueOrDefault)).Leave();
				}
				current_lobby = null;
				isLobbyOwner = false;
			}
			Lobby? val = await SteamMatchmaking.CreateLobbyAsync(maxPlayers.GetValueOrDefault(8));
			if (!val.HasValue)
			{
				Logger.LogError("Lobby creation failed - Result is null");
				return;
			}
			server = new Serveier();
			this.LobbyName = LobbyName;
			if (maxPlayers <= 0)
			{
				maxPlayers = 8;
			}
			this.maxPlayers = maxPlayers.GetValueOrDefault(8);
			this.publicLobby = publicLobby;
			isLobbyOwner = true;
			current_lobby = val;
			ref Lobby? reference4 = ref current_lobby;
			if (reference4.HasValue)
			{
				valueOrDefault = reference4.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetJoinable(true);
			}
			if (publicLobby)
			{
				ref Lobby? reference5 = ref current_lobby;
				if (reference5.HasValue)
				{
					valueOrDefault = reference5.GetValueOrDefault();
					((Lobby)(ref valueOrDefault)).SetPublic();
				}
			}
			else
			{
				ref Lobby? reference6 = ref current_lobby;
				if (reference6.HasValue)
				{
					valueOrDefault = reference6.GetValueOrDefault();
					((Lobby)(ref valueOrDefault)).SetPrivate();
				}
			}
			ref Lobby? reference7 = ref current_lobby;
			if (reference7.HasValue)
			{
				valueOrDefault = reference7.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetData(ModLobbyIDentifiers.Item1, ModLobbyIDentifiers.Item2);
			}
			ref Lobby? reference8 = ref current_lobby;
			if (reference8.HasValue)
			{
				valueOrDefault = reference8.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetData("name", LobbyName);
			}
			ref Lobby? reference9 = ref current_lobby;
			if (reference9.HasValue)
			{
				valueOrDefault = reference9.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetData("mods", mods.ToString());
			}
			ref Lobby? reference10 = ref current_lobby;
			if (reference10.HasValue)
			{
				valueOrDefault = reference10.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetData("members", $"1/{maxPlayers}");
			}
			ref Lobby? reference11 = ref current_lobby;
			if (reference11.HasValue)
			{
				valueOrDefault = reference11.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SetData("Owner", SteamClient.Name);
			}
			ref Lobby? reference12 = ref current_lobby;
			SteamId? obj;
			if (!reference12.HasValue)
			{
				obj = null;
			}
			else
			{
				valueOrDefault = reference12.GetValueOrDefault();
				obj = ((Lobby)(ref valueOrDefault)).Id;
			}
			Logger.ExtraLog($"Lobby Created, id: {obj}");
		}

		public async void JoinLobbyWithID(ulong id)
		{
			try
			{
				server = null;
				Logger.ExtraLog("Joining Lobby with ID");
				Lobby lob = new Lobby(SteamId.op_Implicit(id));
				RoomEnter val = await ((Lobby)(ref lob)).Join();
				if ((int)val == 1)
				{
					Logger.ExtraLog($"Lobby join Success: {val}");
					isLobbyOwner = false;
					current_lobby = lob;
					client = new MultiplayerUtil.Client.Client();
				}
				else
				{
					current_lobby = null;
					isLobbyOwner = false;
					client = null;
					Logger.LogWarning($"Couldn't join the lobby. Result is {val}");
				}
				lob = default(Lobby);
			}
			catch (Exception ex)
			{
				Logger.LogError("An error occurred while trying to join the lobby: " + ex.Message + ", The error might be because steam isnt launched");
			}
		}

		public (byte[], SteamId?) CheckForP2PMessages()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				uint num = default(uint);
				while (SteamNetworking.IsP2PPacketAvailable(ref num, 0))
				{
					SteamId val = default(SteamId);
					byte[] array = new byte[num];
					if (SteamNetworking.ReadP2PPacket(array, ref num, ref val, 0))
					{
						if (!((SteamId)(ref val)).IsValid)
						{
							Logger.ExtraLog("Sender is null skipping");
						}
						else if (!SelfP2PSafeguards || SteamId.op_Implicit(val) != SteamId.op_Implicit(selfID))
						{
							return (array, val);
						}
						continue;
					}
					Logger.ExtraLog($"p2p failed: {val}");
					return (null, null);
				}
			}
			catch (ArgumentException arg)
			{
				Logger.LogError($"CheckForP2p Arg Exeption: {arg}");
			}
			return (null, null);
		}

		public void InviteFriend()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Lobby value = instance.current_lobby.Value;
			SteamFriends.OpenGameInviteOverlay(((Lobby)(ref value)).Id);
		}

		private void OnApplicationQuit()
		{
			Disconnect();
		}

		public void Disconnect()
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (isLobbyOwner)
			{
				if (server.besties.Count > 0)
				{
					foreach (SteamId besty in server.besties)
					{
						SteamNetworking.CloseP2PSessionWithUser(besty);
					}
					Lobby value = current_lobby.Value;
					Friend val = ((Lobby)(ref value)).Members.FirstOrDefault((Func<Friend, bool>)((Friend _) => SteamId.op_Implicit(_.Id) == server.besties[0].Value));
					((Lobby)(ref value)).SendChatString("||| Setting Lobby Owner To: " + ((Friend)(ref val)).Name);
					((Lobby)(ref value)).SetData("members", server.besties.Count.ToString());
					((Lobby)(ref value)).SetData("Owner", ((Friend)(ref val)).Name);
					((Lobby)(ref value)).IsOwnedBy(val.Id);
					Logger.ExtraLog("Setting Lobby Owner to: " + ((Friend)(ref val)).Name);
				}
			}
			else
			{
				foreach (SteamId connectedPeer in client.connectedPeers)
				{
					SteamNetworking.CloseP2PSessionWithUser(connectedPeer);
				}
			}
			ref Lobby? reference = ref current_lobby;
			if (reference.HasValue)
			{
				Lobby valueOrDefault = reference.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).Leave();
			}
			current_lobby = null;
			isLobbyOwner = false;
			server = null;
			client = null;
		}

		public void SendChatMessage(string msg)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			ref Lobby? reference = ref current_lobby;
			if (reference.HasValue)
			{
				Lobby valueOrDefault = reference.GetValueOrDefault();
				((Lobby)(ref valueOrDefault)).SendChatString(msg);
			}
		}

		~SteamManager()
		{
			try
			{
				Disconnect();
			}
			finally
			{
				((object)this).Finalize();
			}
		}
	}
	public static class Callbacks
	{
		public class SenderUnityEvent : UnityEvent<(byte[], SteamId?)>
		{
		}

		public static SenderUnityEvent p2pMessageReceived = new SenderUnityEvent();

		public static UnityEvent TimeToSendImportantData = new UnityEvent();

		public static UnityEvent TimeToSendUnimportantData = new UnityEvent();

		public static UnityEvent StartupComplete = new UnityEvent();

		public static UnityEvent<Lobby, Friend> OnLobbyMemberJoined = new UnityEvent<Lobby, Friend>();

		public static UnityEvent<SteamId> OnLobbyMemberLeave = new UnityEvent<SteamId>();

		public static UnityEvent<Lobby, Friend, string> OnChatMessageReceived = new UnityEvent<Lobby, Friend, string>();

		public static UnityEvent<SteamId, P2PSessionError> OnP2PConnectionFailed = new UnityEvent<SteamId, P2PSessionError>();

		public static UnityEvent<SteamId> OnLobbyMemberBanned = new UnityEvent<SteamId>();

		public static UnityEvent<Lobby> OnLobbyEntered = new UnityEvent<Lobby>();

		public static UnityEvent<Lobby> OnLobbyCreated = new UnityEvent<Lobby>();

		public static Action OnSteamShutdown = delegate
		{
		};
	}
	[Serializable]
	public class NetworkWrapper
	{
		public string ClassType { get; set; }

		public byte[] ClassData { get; set; }
	}
	public static class ObserveManager
	{
		public static bool MessageReceivedLogging = false;

		public static Dictionary<Type, Callbacks.SenderUnityEvent> subscribedEvents = new Dictionary<Type, Callbacks.SenderUnityEvent>();

		public static void SubscribeToType(Type classType, out Callbacks.SenderUnityEvent whenDetected)
		{
			Callbacks.SenderUnityEvent senderUnityEvent = new Callbacks.SenderUnityEvent();
			subscribedEvents.Add(classType, senderUnityEvent);
			whenDetected = senderUnityEvent;
		}

		public static void OnMessageRecived(byte[] message, SteamId? sender)
		{
			NetworkWrapper networkWrapper = null;
			try
			{
				networkWrapper = Data.Deserialize<NetworkWrapper>(message);
			}
			catch (InvalidCastException)
			{
				Logger.LogWarning($"Failed to cast p2p message, sender: {sender}, message len: {message.Length}");
				return;
			}
			if (MessageReceivedLogging)
			{
				Logger.Log($"Recived p2p message, sender: {sender}, type: {networkWrapper.ClassType}, data: {networkWrapper.ClassData}");
			}
			Type type = Type.GetType(networkWrapper.ClassType);
			if (type != null && subscribedEvents.TryGetValue(type, out Callbacks.SenderUnityEvent value))
			{
				((UnityEvent<(byte[], SteamId?)>)(object)value).Invoke((networkWrapper.ClassData, sender));
			}
		}
	}
	public enum AuthoritativeTypes
	{
		Kicked,
		Banned
	}
	public class AuthoritativePacket
	{
		public AuthoritativeTypes type;

		public SteamId id;
	}
	[HarmonyPatch(typeof(SteamController), "Awake")]
	public class SteamControllerAwakePatch
	{
		public static bool Prefix(SteamController __instance)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)SteamController.Instance))
			{
				Object.Destroy((Object)(object)((Component)__instance).gameObject);
				return false;
			}
			SteamController.Instance = __instance;
			((Component)__instance).transform.SetParent((Transform)null);
			Object.DontDestroyOnLoad((Object)(object)((Component)__instance).gameObject);
			try
			{
				SteamClient.Init(_MultiplayerUtil.appId, true);
				SteamManager.instance.selfID = SteamClient.SteamId;
				Debug.Log((object)"Steam initialized!");
			}
			catch (Exception)
			{
				Debug.Log((object)"Couldn't initialize Steam");
			}
			return false;
		}
	}
	public static class Semtings
	{
		private static string modSettingPath;

		public static void Init()
		{
			try
			{
				if (string.IsNullOrEmpty(Paths.ConfigPath))
				{
					Logger.LogError("Config path is not initialized!");
					return;
				}
				modSettingPath = Path.Combine(Paths.ConfigPath, "MultiplayerUtil", "Settings.cfg");
				Directory.CreateDirectory(Path.GetDirectoryName(modSettingPath));
				if (!File.Exists(modSettingPath))
				{
					CreateDefaultSettingsFile();
				}
				else
				{
					LoadExistingSettings();
				}
			}
			catch (Exception ex)
			{
				Logger.LogError("Error in Init(): " + ex.Message);
				Debug.LogException(ex);
			}
		}

		private static void CreateDefaultSettingsFile()
		{
			try
			{
				string contents = JsonUtility.ToJson((object)new Settings
				{
					cracked = false
				}, true);
				File.WriteAllText(modSettingPath, contents);
			}
			catch (Exception ex)
			{
				Logger.LogError("Failed to create settings file: " + ex.Message);
			}
		}

		private static void LoadExistingSettings()
		{
			try
			{
				Settings settings = JsonUtility.FromJson<Settings>(File.ReadAllText(modSettingPath));
				if (settings == null)
				{
					Logger.LogError("Failed to deserialize settings. Creating default.");
					CreateDefaultSettingsFile();
				}
				else
				{
					_MultiplayerUtil.cracked = settings.cracked;
				}
			}
			catch (Exception ex)
			{
				Logger.LogError("Error loading settings: " + ex.Message);
				CreateDefaultSettingsFile();
			}
		}
	}
	[Serializable]
	public class Settings
	{
		public bool cracked;
	}
	public enum SendMethod
	{
		Unreliable,
		UnreliableNoDelay,
		Reliable,
		ReliableWithBuffering
	}
}
namespace MultiplayerUtil.Server
{
	public class Serveier
	{
		public List<SteamId> besties = new List<SteamId>();

		public Serveier()
		{
			SteamManager.instance.dataLoop = ((MonoBehaviour)SteamManager.instance).StartCoroutine(SteamManager.instance.DataLoopInit());
		}

		public void Send(object data, SendMethod sendMethod)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = ((!(data is byte[])) ? Data.Serialize(data) : ((byte[])data));
			foreach (SteamId besty in besties)
			{
				ulong value = besty.Value;
				if (SteamManager.SelfP2PSafeguards && value == SteamId.op_Implicit(LobbyManager.selfID))
				{
					break;
				}
				P2PSend val = Data.ConvertSendMethodToP2PSend(sendMethod);
				if (!SteamNetworking.SendP2PPacket(SteamId.op_Implicit(value), array, array.Length, 0, val))
				{
					Logger.LogError($"Failed to send P2P packet to {value}", Client: false);
				}
			}
		}
	}
}
namespace MultiplayerUtil.Client
{
	public class Client
	{
		public List<SteamId> connectedPeers = new List<SteamId>();

		public void Connect(SteamId hostId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (SteamManager.instance.EstablishP2P(hostId))
			{
				connectedPeers.Add(hostId);
				SteamManager.instance.dataLoop = ((MonoBehaviour)SteamManager.instance).StartCoroutine(SteamManager.instance.DataLoopInit());
				Logger.Log($"P2P Connection established with {hostId}", Client: true);
			}
			else
			{
				Logger.LogError($"Failed to establish P2P connection with {hostId}", Client: true);
			}
		}

		public void Send(object data, SendMethod sendMethod)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = ((!(data is byte[])) ? Data.Serialize(data) : ((byte[])data));
			foreach (SteamId connectedPeer in connectedPeers)
			{
				if (SteamManager.SelfP2PSafeguards && SteamId.op_Implicit(connectedPeer) == SteamId.op_Implicit(LobbyManager.selfID))
				{
					break;
				}
				P2PSend val = Data.ConvertSendMethodToP2PSend(sendMethod);
				if (!SteamNetworking.SendP2PPacket(connectedPeer, array, array.Length, 0, val))
				{
					Logger.LogError($"Failed to send P2P packet to {connectedPeer}", Client: true);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}