using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using IronLabs.SharedLib; using PlayFab; using PlayFab.MultiplayerModels; using PlayFab.Party; using Steamworks; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("IronLabs.ExpandedServer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("IronLabs.ExpandedServer")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("BC3CCFF6-4C9F-4610-963F-06DAC8828ADC")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.1.39046")] namespace IronLabs.ExpandedServer { [BepInPlugin("IronLabs.ExpandedServer", "IronLabs.ExpandedServer", "1.0.1")] public sealed class ExpandedServerPlugin : IronLabsPlugin { private const string PluginGuid = "IronLabs.ExpandedServer"; private const string PluginName = "IronLabs.ExpandedServer"; private const string PluginVersion = "1.0.1"; private const int DefaultMaxPlayers = 20; private const int MaximumMaxPlayers = 100; internal static int MaxPlayers { get; private set; } = 20; internal static bool IsLocalServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } internal static ModLog Log { get; private set; } private void Awake() { Log = InitializePlugin("IronLabs.ExpandedServer"); MaxPlayers = ReadMaxPlayers(); Log.LogInfo(string.Format("{0} {1} is loaded with a {2}-player limit.", "IronLabs.ExpandedServer", "1.0.1", MaxPlayers)); } private static int ReadMaxPlayers() { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 0; i < commandLineArgs.Length; i++) { if (string.Equals(commandLineArgs[i], "--maxplayer", StringComparison.OrdinalIgnoreCase)) { if (i + 1 >= commandLineArgs.Length || !int.TryParse(commandLineArgs[i + 1], out var result) || result < 1) { Log.LogWarning("Invalid --maxplayer value; using the default limit of 20."); return 20; } int num = Math.Min(result, 100); Log.LogDebug($"Received command-line switch: --maxplayer {result}; limit={num}."); return num; } } Log.LogDebug("No --maxplayer switch was provided; using the default limit of 20."); return 20; } private void OnDestroy() { ShutdownPlugin(); Log = null; } } [HarmonyPatch(typeof(PlayFabMultiplayerAPI), "CreateLobby")] internal static class IncreasePlayFabLobbyPlayerLimitPatch { private static void Prefix(CreateLobbyRequest request) { if (request != null && ExpandedServerPlugin.IsLocalServer && request.MaxPlayers != ExpandedServerPlugin.MaxPlayers) { request.MaxPlayers = (uint)ExpandedServerPlugin.MaxPlayers; ExpandedServerPlugin.Log.LogDebug($"PlayFab lobby capacity set to {request.MaxPlayers} players."); } } } [HarmonyPatch(typeof(PlayFabMultiplayerManager), "CreateAndJoinNetwork", new Type[] { typeof(PlayFabNetworkConfiguration) })] internal static class IncreasePlayFabNetworkPlayerLimitPatch { private static void Prefix(PlayFabNetworkConfiguration networkConfiguration) { if (networkConfiguration != null && ExpandedServerPlugin.IsLocalServer && networkConfiguration.MaxPlayerCount != ExpandedServerPlugin.MaxPlayers) { networkConfiguration.MaxPlayerCount = (uint)ExpandedServerPlugin.MaxPlayers; ExpandedServerPlugin.Log.LogDebug($"PlayFab network capacity set to {networkConfiguration.MaxPlayerCount} players."); } } } [HarmonyPatch(typeof(SteamGameServer), "SetMaxPlayerCount")] internal static class IncreaseSteamPlayerLimitPatch { private static void Prefix(ref int cPlayersMax) { if (ExpandedServerPlugin.IsLocalServer && cPlayersMax != ExpandedServerPlugin.MaxPlayers) { cPlayersMax = ExpandedServerPlugin.MaxPlayers; ExpandedServerPlugin.Log.LogDebug($"Steam server capacity set to {cPlayersMax} players."); } } } [HarmonyPatch(typeof(SteamMatchmaking), "CreateLobby", new Type[] { typeof(ELobbyType), typeof(int) })] internal static class SetSteamLobbyPlayerLimitPatch { private static void Prefix(ref int cMaxMembers) { if (ExpandedServerPlugin.IsLocalServer && cMaxMembers != ExpandedServerPlugin.MaxPlayers) { cMaxMembers = ExpandedServerPlugin.MaxPlayers; ExpandedServerPlugin.Log.LogDebug($"Steam lobby capacity set to {cMaxMembers} players."); } } } [HarmonyPatch(typeof(ZNet), "GetNrOfPlayers")] internal static class AllowPeerInfoUntilServerPlayerLimitPatch { private static bool _logged; private static void Postfix(ref int __result) { if (ExpandedServerPlugin.IsLocalServer && IncreaseServerPlayerLimitPatch.IsCheckingPeerInfo) { int num = __result; if (num >= ExpandedServerPlugin.MaxPlayers) { __result = 10; } else if (num >= 10) { __result = 9; LogRaisedAdmissionLimit(); } } } private static void LogRaisedAdmissionLimit() { if (!_logged) { _logged = true; ExpandedServerPlugin.Log.LogDebug($"Server admission limit increased to {ExpandedServerPlugin.MaxPlayers} players."); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] internal static class IncreaseServerPlayerLimitPatch { [ThreadStatic] private static int _peerInfoDepth; internal static bool IsCheckingPeerInfo => _peerInfoDepth > 0; private static void Prefix() { _peerInfoDepth++; } private static void Finalizer() { if (_peerInfoDepth > 0) { _peerInfoDepth--; } } } } namespace IronLabs.SharedLib { public abstract class IronLabsPlugin : BaseUnityPlugin { private Harmony _harmony; private bool _patchesApplied; protected ModLog InitializePlugin(string pluginGuid) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger); Version version = ((object)this).GetType().Assembly.GetName().Version; modLog.LogInfo($"AssemblyVersion: {version}."); _harmony = new Harmony(pluginGuid); PatchOwnNamespace(modLog); return modLog; } protected void PatchOwnNamespace(ModLog log) { if (_patchesApplied) { log.LogDebug("Harmony patches are already active; skipping registration."); return; } string text = ((object)this).GetType().Namespace; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { if (type.Namespace == text) { _harmony.CreateClassProcessor(type).Patch(); } } _patchesApplied = true; log.LogDebug("Harmony patches were applied for the plugin namespace."); } protected void ShutdownPlugin() { if (_patchesApplied) { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _patchesApplied = false; } } } public sealed class ModLog { private readonly ManualLogSource _logger; public ModLog(ManualLogSource logger) { _logger = logger; } public void LogFatal(object message) { Write((LogLevel)1, message); } public void LogError(object message) { Write((LogLevel)2, message); } public void LogWarning(object message) { Write((LogLevel)4, message); } public void LogMessage(object message) { Write((LogLevel)8, message); } public void LogInfo(object message) { Write((LogLevel)16, message); } public void LogDebug(object message) { Write((LogLevel)32, message); } public void Log(LogLevel level, object message) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Write(level, message); } private void Write(LogLevel level, object message) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) string arg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); _logger.Log(level, (object)$"[{arg}] {message}"); } } }