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;
}
}