Decompiled source of MorePlayersCS v1.0.0

plugins/MorePlayersCS.dll

Decompiled 13 hours ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace MorePlayersCS;

[BepInPlugin("allan.crimesim.moreplayers", "More Players", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	public const string Guid = "allan.crimesim.moreplayers";

	internal static ManualLogSource Log;

	internal static ConfigEntry<int> MaxPlayers;

	private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private void Awake()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		MaxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPlayers", 8, new ConfigDescription("Maximo de jugadores por sala (el juego trae 4).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 32), Array.Empty<object>()));
		Harmony harmony = new Harmony("allan.crimesim.moreplayers");
		int num = 0;
		if (PatchSteam(harmony))
		{
			num++;
		}
		if (PatchFusion(harmony))
		{
			num++;
		}
		Log.LogInfo((object)$"More Players cargado: limite = {MaxPlayers.Value}, parches aplicados = {num}/2");
	}

	private static bool PatchSteam(Harmony harmony)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		try
		{
			Type type = AccessTools.TypeByName("Steamworks.SteamMatchmaking");
			MethodInfo methodInfo = ((!(type == null)) ? AccessTools.Method(type, "CreateLobby", (Type[])null, (Type[])null) : null);
			if (methodInfo == null)
			{
				Log.LogWarning((object)"No encontre SteamMatchmaking.CreateLobby");
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "SteamPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Fallo parche Steam: " + ex));
			return false;
		}
	}

	private static void SteamPrefix(object[] __args)
	{
		int num = default(int);
		for (int i = 0; i < __args.Length; i++)
		{
			object obj = __args[i];
			object obj2 = ((obj is int) ? obj : null);
			if (obj2 != null)
			{
				num = (int)obj;
			}
			if (obj2 != null && num < MaxPlayers.Value)
			{
				Log.LogInfo((object)$"CreateLobby: maxMembers {num} -> {MaxPlayers.Value}");
				__args[i] = MaxPlayers.Value;
			}
		}
	}

	private static bool PatchFusion(Harmony harmony)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		try
		{
			Type type = AccessTools.TypeByName("Fusion.NetworkRunner");
			if (type == null)
			{
				Log.LogWarning((object)"No encontre Fusion.NetworkRunner");
				return false;
			}
			int num = 0;
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
			{
				if (!(declaredMethod.Name != "StartGame"))
				{
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					if (parameters.Length == 1 && !(parameters[0].ParameterType.Name != "StartGameArgs"))
					{
						harmony.Patch((MethodBase)declaredMethod, new HarmonyMethod(typeof(Plugin), "FusionPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
					}
				}
			}
			if (num == 0)
			{
				Log.LogWarning((object)"No encontre NetworkRunner.StartGame(StartGameArgs)");
			}
			return num > 0;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Fallo parche Fusion: " + ex));
			return false;
		}
	}

	private static void FusionPrefix(object[] __args)
	{
		try
		{
			if (__args == null || __args.Length == 0 || __args[0] == null)
			{
				return;
			}
			object obj = __args[0];
			Type type = obj.GetType();
			object member = GetMember(type, obj, "GameMode");
			if (member == null || !(member.ToString() == "Single"))
			{
				object member2 = GetMember(type, obj, "PlayerCount");
				object obj2 = ((member2 is int) ? member2 : null);
				int num = default(int);
				if (obj2 != null)
				{
					num = (int)member2;
				}
				if (obj2 != null && num < MaxPlayers.Value && SetMember(type, obj, "PlayerCount", MaxPlayers.Value))
				{
					__args[0] = obj;
					Log.LogInfo((object)$"StartGame: PlayerCount {num} -> {MaxPlayers.Value}");
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("FusionPrefix: " + ex));
		}
	}

	private static object GetMember(Type t, object o, string name)
	{
		FieldInfo field = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return field.GetValue(o);
		}
		PropertyInfo property = t.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		return (!(property != null) || !property.CanRead) ? null : property.GetValue(o, null);
	}

	private static bool SetMember(Type t, object o, string name, object value)
	{
		FieldInfo field = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			field.SetValue(o, value);
			return true;
		}
		PropertyInfo property = t.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (property != null && property.CanWrite)
		{
			property.SetValue(o, value, null);
			return true;
		}
		return false;
	}
}