Decompiled source of SledBigLobbies v0.1.0

SledBigLobbies.dll

Decompiled 2 days ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using MelonLoader;
using SledBigLobbies;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SledBigLobbies")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: MelonInfo(typeof(Mod), "SledBigLobbies", "0.1.0", "Natebag", null)]
[assembly: MelonGame("The Sledding Corporation", "Sledding Game")]
[assembly: MelonColor(255, 255, 200, 80)]
[assembly: MelonAuthorColor(255, 80, 160, 255)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace SledBigLobbies;

public sealed class Mod : MelonMod
{
	public const string Name = "SledBigLobbies";

	public const string Version = "0.1.0";

	public const string Author = "Natebag";

	internal const int MaxPlayers = 60;

	internal const int MinPlayers = 1;

	internal const bool ForceCrossplay = true;

	private static float _nextEnforce;

	private static Type _lsmType;

	private static MethodInfo _lsmGetInstance;

	private static MethodInfo _lsmGetSettings;

	private static bool _enforceLogged;

	private static int _enforceCount;

	private static float _enforceLogAt;

	private static bool _uiSliderWarned;

	private static bool _crossplayLogged;

	private const int AttrTypeMaxPlayers = 9;

	private static MethodInfo _objectOpImplicitFromInt;

	private static MethodInfo _int32OpImplicitFromInt;

	private static bool _boxLookupAttempted;

	private static bool _shapeLogged;

	private static bool _lobbyMutLogged;

	private static bool _lsLoggedShape;

	public override void OnUpdate()
	{
		EnforceLobbyCap();
	}

	private static void EnforceLobbyCap()
	{
		if (Time.time < _nextEnforce)
		{
			return;
		}
		_nextEnforce = Time.time + 0.5f;
		try
		{
			if (_lsmType == null)
			{
				_lsmType = FindTypeByShortName("LobbySettingsManager");
				if (_lsmType == null)
				{
					return;
				}
				_lsmGetInstance = _lsmType.GetMethod("get_Instance", BindingFlags.Static | BindingFlags.Public);
				_lsmGetSettings = _lsmType.GetMethod("GetLobbySettings", BindingFlags.Instance | BindingFlags.Public);
			}
			if (_lsmGetInstance == null || _lsmGetSettings == null)
			{
				return;
			}
			object obj = _lsmGetInstance.Invoke(null, null);
			if (obj == null)
			{
				return;
			}
			object obj2 = _lsmGetSettings.Invoke(obj, null);
			if (obj2 == null)
			{
				return;
			}
			Type type = obj2.GetType();
			int num = 60;
			PropertyInfo property = type.GetProperty("maxPlayers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanRead && property.CanWrite)
			{
				int num2 = (int)(property.GetValue(obj2) ?? ((object)0));
				if (num2 < num)
				{
					property.SetValue(obj2, num);
					LogEnforce($"enforce prop {num2}->{num}");
				}
				return;
			}
			FieldInfo field = type.GetField("maxPlayers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				int num3 = (int)(field.GetValue(obj2) ?? ((object)0));
				if (num3 < num)
				{
					field.SetValue(obj2, num);
					LogEnforce($"enforce field {num3}->{num}");
				}
			}
			else if (!_enforceLogged)
			{
				_enforceLogged = true;
				string value = string.Join(",", (from x in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					select "p:" + x.Name).Concat(from x in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					select "f:" + x.Name));
				MelonLogger.Msg($"[SledBigLobbies] enforce: no maxPlayers member found on {type.FullName}; members=[{value}]");
			}
		}
		catch (Exception ex)
		{
			LogEnforce("enforce error: " + ex.Message);
		}
	}

	private static void LogEnforce(string msg)
	{
		_enforceCount++;
		if (_enforceCount <= 3 || Time.time > _enforceLogAt + 1f)
		{
			_enforceLogAt = Time.time;
			MelonLogger.Msg($"[SledBigLobbies] {msg} (#{_enforceCount})");
		}
	}

	public override void OnInitializeMelon()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Expected O, but got Unknown
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Expected O, but got Unknown
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Expected O, but got Unknown
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bc: Expected O, but got Unknown
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Expected O, but got Unknown
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Expected O, but got Unknown
		try
		{
			Harmony val = new Harmony("Natebag.SledBigLobbies");
			int num = 0;
			Type type = FindType("Assembly-CSharp", "_Scripts.Managers.LobbyManager") ?? FindType("Assembly-CSharp", "LobbyManager");
			if (type == null)
			{
				((MelonBase)this).LoggerInstance.Warning("LobbyManager type not found — lobby cap won't be raised");
			}
			else
			{
				MethodInfo method = type.GetMethod("CreateLobby", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
				if (method == null)
				{
					((MelonBase)this).LoggerInstance.Warning("LobbyManager.CreateLobby method not found");
				}
				else
				{
					MethodInfo method2 = typeof(Mod).GetMethod("CreateLobby_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
			Type type2 = FindType("Il2CppFishyEOS", "FishNet.Transporting.FishyEOSPlugin.FishyEOS") ?? FindType("Fishnet.Plugins.FishyEOS", "FishNet.Transporting.FishyEOSPlugin.FishyEOS") ?? FindTypeByShortName("FishyEOS");
			if (type2 != null)
			{
				MethodInfo method3 = type2.GetMethod("SetMaximumClients", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
				if (method3 != null)
				{
					MethodInfo method4 = typeof(Mod).GetMethod("SetMaximumClients_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method3, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
			Type type3 = FindType("Il2CppFishNet.Runtime", "FishNet.Transporting.Tugboat.Tugboat") ?? FindType("FishNet.Runtime", "FishNet.Transporting.Tugboat.Tugboat") ?? FindTypeByShortName("Tugboat");
			if (type3 != null)
			{
				MethodInfo method5 = type3.GetMethod("SetMaximumClients", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
				if (method5 != null)
				{
					MethodInfo method6 = typeof(Mod).GetMethod("SetMaximumClients_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method5, new HarmonyMethod(method6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
			Type type4 = FindType("com.rlabrecque.steamworks.net", "Steamworks.SteamMatchmaking") ?? FindTypeByShortName("SteamMatchmaking");
			if (type4 != null)
			{
				MethodInfo method7 = type4.GetMethod("CreateLobby", BindingFlags.Static | BindingFlags.Public);
				if (method7 != null)
				{
					MethodInfo method8 = typeof(Mod).GetMethod("Steam_CreateLobby_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method7, new HarmonyMethod(method8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("SteamMatchmaking.CreateLobby not found");
				}
				MethodInfo method9 = type4.GetMethod("SetLobbyMemberLimit", BindingFlags.Static | BindingFlags.Public);
				if (method9 != null)
				{
					MethodInfo method10 = typeof(Mod).GetMethod("Steam_SetLobbyMemberLimit_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method9, new HarmonyMethod(method10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("SteamMatchmaking.SetLobbyMemberLimit not found");
				}
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("SteamMatchmaking type not found — Steam lobby cap won't be raised");
			}
			if (type != null)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != "AddAttribute") && methodInfo.GetParameters().Length >= 3)
					{
						MethodInfo method11 = typeof(Mod).GetMethod("AddAttribute_Prefix", BindingFlags.Static | BindingFlags.NonPublic);
						val.Patch((MethodBase)methodInfo, new HarmonyMethod(method11), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
						break;
					}
				}
			}
			Type type5 = FindType("Assembly-CSharp", "LobbySettings");
			if (type5 != null)
			{
				int num2 = 0;
				ConstructorInfo[] constructors = type5.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (ConstructorInfo constructorInfo in constructors)
				{
					if (constructorInfo.GetParameters().Length >= 5)
					{
						MethodInfo method12 = typeof(Mod).GetMethod("LobbySettings_Ctor_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
						val.Patch((MethodBase)constructorInfo, (HarmonyMethod)null, new HarmonyMethod(method12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num2++;
					}
				}
				if (num2 > 0)
				{
					num++;
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("LobbySettings ctor with maxPlayers param not found");
				}
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("LobbySettings type not found");
			}
			Type type6 = FindType("Assembly-CSharp", "_Scripts.UI.Pre_Game.UICreateLobby") ?? FindTypeByShortName("UICreateLobby");
			if (type6 != null)
			{
				MethodInfo method13 = type6.GetMethod("ShowPanel", BindingFlags.Instance | BindingFlags.Public);
				if (method13 != null)
				{
					MethodInfo method14 = typeof(Mod).GetMethod("UICreateLobby_ShowPanel_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
					val.Patch((MethodBase)method13, (HarmonyMethod)null, new HarmonyMethod(method14), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("UICreateLobby.ShowPanel not found — vanilla slider stays capped");
				}
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("UICreateLobby type not found — vanilla slider stays capped");
			}
			((MelonBase)this).LoggerInstance.Msg($"SledBigLobbies v{"0.1.0"} ready — host cap = {60}, {num} patches installed.");
			if (num == 0)
			{
				((MelonBase)this).LoggerInstance.Warning("No patches installed — game may have updated; mod is no-op until updated.");
			}
		}
		catch (Exception value)
		{
			((MelonBase)this).LoggerInstance.Error($"SledBigLobbies init failed: {value}");
		}
	}

	private static void CreateLobby_Prefix(ref int maxPlayers)
	{
		try
		{
			int value = maxPlayers;
			if (maxPlayers < 60)
			{
				maxPlayers = 60;
			}
			MelonLogger.Msg($"[SledBigLobbies] CreateLobby: maxPlayers {value}->{maxPlayers}");
		}
		catch
		{
		}
	}

	private static void UICreateLobby_ShowPanel_Postfix(object __instance)
	{
		try
		{
			object obj = ReadMember(__instance, "maxPlayersSlider");
			if (obj == null)
			{
				if (!_uiSliderWarned)
				{
					MelonLogger.Warning("[SledBigLobbies] maxPlayersSlider not readable on UICreateLobby");
					_uiSliderWarned = true;
				}
				return;
			}
			object obj2 = ReadMember(obj, "slider");
			if (obj2 == null)
			{
				if (!_uiSliderWarned)
				{
					MelonLogger.Warning("[SledBigLobbies] inner slider not readable on MySliderUI");
					_uiSliderWarned = true;
				}
				return;
			}
			PropertyInfo property = obj2.GetType().GetProperty("maxValue", BindingFlags.Instance | BindingFlags.Public);
			PropertyInfo property2 = obj2.GetType().GetProperty("minValue", BindingFlags.Instance | BindingFlags.Public);
			if (property == null)
			{
				if (!_uiSliderWarned)
				{
					MelonLogger.Warning("[SledBigLobbies] Slider.maxValue property missing");
					_uiSliderWarned = true;
				}
				return;
			}
			float num = (float)(property.GetValue(obj2) ?? ((object)0f));
			if (num < 60f)
			{
				property.SetValue(obj2, 60f);
				MelonLogger.Msg($"[SledBigLobbies] UICreateLobby slider max: {num} -> {60}");
			}
			if (property2 != null)
			{
				float num2 = (float)(property2.GetValue(obj2) ?? ((object)0f));
				if (num2 > 1f)
				{
					property2.SetValue(obj2, 1f);
					MelonLogger.Msg($"[SledBigLobbies] UICreateLobby slider min: {num2} -> {1}");
				}
			}
			TryForceCrossplay(__instance);
		}
		catch (Exception ex)
		{
			if (!_uiSliderWarned)
			{
				MelonLogger.Warning("[SledBigLobbies] UICreateLobby_ShowPanel_Postfix: " + ex.Message);
				_uiSliderWarned = true;
			}
		}
	}

	private static void TryForceCrossplay(object createLobbyUI)
	{
		try
		{
			Type type = createLobbyUI.GetType();
			bool value = false;
			PropertyInfo property = type.GetProperty("_hasCrossplayPrivilege", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				property.SetValue(createLobbyUI, true);
				value = true;
			}
			else
			{
				FieldInfo field = type.GetField("_hasCrossplayPrivilege", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(createLobbyUI, true);
					value = true;
				}
			}
			object obj = null;
			PropertyInfo property2 = type.GetProperty("crossplayToggle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property2 != null && property2.CanRead)
			{
				obj = property2.GetValue(createLobbyUI);
			}
			if (obj == null)
			{
				FieldInfo field2 = type.GetField("crossplayToggle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					obj = field2.GetValue(createLobbyUI);
				}
			}
			bool value2 = false;
			bool value3 = false;
			if (obj != null)
			{
				object obj2 = obj.GetType().GetProperty("gameObject", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj);
				if (obj2 != null)
				{
					MethodInfo method = obj2.GetType().GetMethod("SetActive", new Type[1] { typeof(bool) });
					if (method != null)
					{
						method.Invoke(obj2, new object[1] { true });
						value2 = true;
					}
				}
				PropertyInfo property3 = obj.GetType().GetProperty("interactable", BindingFlags.Instance | BindingFlags.Public);
				if (property3 != null && property3.CanWrite)
				{
					property3.SetValue(obj, true);
					value3 = true;
				}
			}
			if (!_crossplayLogged)
			{
				_crossplayLogged = true;
				MelonLogger.Msg($"[SledBigLobbies] crossplay force: privilege={value} go.SetActive={value2} interactable={value3} (toggle={((obj != null) ? "found" : "null")})");
			}
		}
		catch (Exception ex)
		{
			if (!_crossplayLogged)
			{
				_crossplayLogged = true;
				MelonLogger.Warning("[SledBigLobbies] TryForceCrossplay: " + ex.Message);
			}
		}
	}

	private static object ReadMember(object owner, string name)
	{
		if (owner == null)
		{
			return null;
		}
		Type type = owner.GetType();
		try
		{
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanRead)
			{
				return property.GetValue(owner);
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				return field.GetValue(owner);
			}
		}
		catch
		{
		}
		return null;
	}

	private static void SetMaximumClients_Prefix(ref int value)
	{
		try
		{
			int num = 60;
			int value2 = value;
			if (value < num)
			{
				value = num;
			}
			MelonLogger.Msg($"[SledBigLobbies] SetMaximumClients: vanilla wanted {value2}, rewrote to {value}");
		}
		catch
		{
		}
	}

	private static void Steam_CreateLobby_Prefix(ref int cMaxMembers)
	{
		try
		{
			int num = 60;
			int value = cMaxMembers;
			if (cMaxMembers < num)
			{
				cMaxMembers = num;
			}
			MelonLogger.Msg($"[SledBigLobbies] Steam CreateLobby: vanilla wanted cMaxMembers={value}, rewrote to {cMaxMembers}");
		}
		catch
		{
		}
	}

	private static void Steam_SetLobbyMemberLimit_Prefix(ref int cMaxMembers)
	{
		try
		{
			int num = 60;
			int value = cMaxMembers;
			if (cMaxMembers < num)
			{
				cMaxMembers = num;
			}
			MelonLogger.Msg($"[SledBigLobbies] Steam SetLobbyMemberLimit: vanilla wanted {value}, rewrote to {cMaxMembers}");
		}
		catch
		{
		}
	}

	private static void AddAttribute_Prefix(object lobby, object type, ref object value)
	{
		try
		{
			int num;
			try
			{
				num = Convert.ToInt32(type);
			}
			catch
			{
				return;
			}
			if (num == 9)
			{
				EnsureBoxLookup();
				MethodInfo methodInfo = _objectOpImplicitFromInt ?? _int32OpImplicitFromInt;
				if (!(methodInfo == null))
				{
					int num2 = 60;
					string value2 = value?.GetType().FullName ?? "(null)";
					object obj2 = methodInfo.Invoke(null, new object[1] { num2 });
					value = obj2;
					MelonLogger.Msg($"[SledBigLobbies] AddAttribute MAXPLAYERS: replaced ({value2}) -> {methodInfo.DeclaringType?.Name}({num2})");
					TryForceLobbyMaxMembers(lobby, (uint)num2);
				}
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("[SledBigLobbies] AddAttribute_Prefix: " + ex.Message);
		}
	}

	private static void TryForceLobbyMaxMembers(object lobby, uint target)
	{
		if (lobby == null)
		{
			return;
		}
		try
		{
			Type type = lobby.GetType();
			PropertyInfo property = type.GetProperty("MaxNumLobbyMembers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				property.SetValue(lobby, target);
				if (!_lobbyMutLogged)
				{
					_lobbyMutLogged = true;
					MelonLogger.Msg($"[SledBigLobbies] Lobby.MaxNumLobbyMembers <- {target} via property");
				}
				return;
			}
			FieldInfo field = type.GetField("MaxNumLobbyMembers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(lobby, target);
				if (!_lobbyMutLogged)
				{
					_lobbyMutLogged = true;
					MelonLogger.Msg($"[SledBigLobbies] Lobby.MaxNumLobbyMembers <- {target} via field");
				}
			}
			else if (!_lobbyMutLogged)
			{
				_lobbyMutLogged = true;
				string value = string.Join(",", (from x in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
					select "p:" + x.Name).Concat(from x in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
					select "f:" + x.Name));
				MelonLogger.Msg($"[SledBigLobbies] no MaxNumLobbyMembers on Lobby type={type.FullName} members=[{value}]");
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("[SledBigLobbies] TryForceLobbyMaxMembers: " + ex.Message);
		}
	}

	private static void EnsureBoxLookup()
	{
		if (_boxLookupAttempted)
		{
			return;
		}
		_boxLookupAttempted = true;
		try
		{
			Type type = null;
			Type type2 = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (type == null)
				{
					try
					{
						type = assembly.GetType("Il2CppSystem.Object");
					}
					catch
					{
					}
				}
				if (type2 == null)
				{
					try
					{
						type2 = assembly.GetType("Il2CppSystem.Int32");
					}
					catch
					{
					}
				}
				if (type != null && type2 != null)
				{
					break;
				}
			}
			_objectOpImplicitFromInt = FindOpImplicitFromInt(type);
			_int32OpImplicitFromInt = FindOpImplicitFromInt(type2);
			if (_shapeLogged)
			{
				return;
			}
			_shapeLogged = true;
			MelonLogger.Msg("[SledBigLobbies] box lookup: ObjectType=" + (type?.FullName ?? "null") + " Int32Type=" + (type2?.FullName ?? "null"));
			MelonLogger.Msg($"[SledBigLobbies] box paths: Object.op_Implicit(int)={_objectOpImplicitFromInt != null}, Int32.op_Implicit(int)={_int32OpImplicitFromInt != null}");
			if (!(_objectOpImplicitFromInt == null) || !(_int32OpImplicitFromInt == null) || !(type != null))
			{
				return;
			}
			string text = string.Join(",", from m in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
				where m.Name.StartsWith("op_")
				select $"{m.Name}({string.Join(",", from p in m.GetParameters()
					select p.ParameterType.Name)})->{m.ReturnType.Name}");
			MelonLogger.Msg("[SledBigLobbies] Object op_* methods: [" + text + "]");
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("[SledBigLobbies] EnsureBoxLookup: " + ex.Message);
		}
	}

	private static void LobbySettings_Ctor_Postfix(object __instance)
	{
		try
		{
			if (__instance == null)
			{
				return;
			}
			Type type = __instance.GetType();
			int num = 60;
			int? value = null;
			object obj = null;
			PropertyInfo property = type.GetProperty("maxPlayers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanRead && property.CanWrite)
			{
				try
				{
					value = (int)(property.GetValue(__instance) ?? ((object)0));
					obj = property;
				}
				catch
				{
				}
			}
			if (obj == null)
			{
				FieldInfo field = type.GetField("maxPlayers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					try
					{
						value = (int)(field.GetValue(__instance) ?? ((object)0));
						obj = field;
					}
					catch
					{
					}
				}
			}
			if (!_lsLoggedShape)
			{
				_lsLoggedShape = true;
				MelonLogger.Msg($"[SledBigLobbies] LobbySettings ctor: type={type.FullName} writeVia={obj?.GetType().Name ?? "(null)"} current={value}");
			}
			if (obj != null && value.HasValue && value.Value < num)
			{
				if (obj is PropertyInfo propertyInfo)
				{
					propertyInfo.SetValue(__instance, num);
				}
				else if (obj is FieldInfo fieldInfo)
				{
					fieldInfo.SetValue(__instance, num);
				}
				MelonLogger.Msg($"[SledBigLobbies] LobbySettings.maxPlayers: {value} -> {num}");
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("[SledBigLobbies] LobbySettings_Ctor_Postfix: " + ex.Message);
		}
	}

	private static MethodInfo FindOpImplicitFromInt(Type onType)
	{
		if (onType == null)
		{
			return null;
		}
		MethodInfo[] methods = onType.GetMethods(BindingFlags.Static | BindingFlags.Public);
		foreach (MethodInfo methodInfo in methods)
		{
			if (!(methodInfo.Name != "op_Implicit"))
			{
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length == 1 && parameters[0].ParameterType == typeof(int))
				{
					return methodInfo;
				}
			}
		}
		return null;
	}

	private static Type FindType(string asmHint, string fullName)
	{
		try
		{
			string[] array = new string[3]
			{
				fullName,
				"Il2Cpp." + fullName,
				"Il2Cpp" + fullName
			};
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				string[] array2 = array;
				foreach (string name in array2)
				{
					Type type;
					try
					{
						type = assembly.GetType(name);
					}
					catch
					{
						continue;
					}
					if (type != null)
					{
						return type;
					}
				}
			}
			int num = fullName.LastIndexOf('.');
			string text = ((num >= 0) ? fullName.Substring(num + 1) : fullName);
			assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly2.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					types = ex.Types;
				}
				catch
				{
					continue;
				}
				Type[] array3 = types;
				foreach (Type type2 in array3)
				{
					if (!(type2 == null) && !(type2.Name != text) && type2.FullName != null && (type2.FullName.EndsWith("." + fullName) || type2.FullName.EndsWith(fullName) || type2.FullName == fullName))
					{
						return type2;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static Type FindTypeByShortName(string shortName)
	{
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					types = ex.Types;
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (!(type == null) && type.Name == shortName)
					{
						return type;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}
}