Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RoboUnion v0.6.2
RoboUnion.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Unity.VisualScripting; using UnityEngine; [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("linkoid")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("[MorePlayers] The Robo Union empowers YOU \ud83e\udef5 to safely increase (or decrease) the maximum number of workers on a R.E.P.O. team. Leave no Semibot behind!")] [assembly: AssemblyFileVersion("0.6.2.0")] [assembly: AssemblyInformationalVersion("0.6.2+a4bfb5565582a39026935be371a54fd8ac9bb86f")] [assembly: AssemblyProduct("RoboUnion")] [assembly: AssemblyTitle("RoboUnion")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/linkoid/Repo.RoboUnion")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.6.2.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; } } internal static class IsExternalInit { } } namespace Linkoid.Repo.RoboUnion { internal record ConfigModel(ConfigFile ConfigFile) { internal const string GeneralSection = "General"; public readonly ConfigEntry<int> MaxPlayers = ConfigFile.Bind<int>("General", "MaxPlayers", 10, new ConfigDescription("Sets the maximum number of players allowed in a multiplayer lobby. 0 = Default", (AcceptableValueBase)null, Array.Empty<object>())); internal const string DeveloperSection = "Developer"; public readonly ConfigEntry<bool> LogMessagesPerSecond = ConfigFile.Bind<bool>("Developer", "LogMessagesPerSecond", false, (ConfigDescription)null); public readonly ConfigEntry<bool> ShowMessagesPerSecond = ConfigFile.Bind<bool>("Developer", "ShowMessagesPerSecond", false, (ConfigDescription)null); [CompilerGenerated] protected ConfigModel(ConfigModel original) { ConfigFile = original.ConfigFile; MaxPlayers = original.MaxPlayers; LogMessagesPerSecond = original.LogMessagesPerSecond; ShowMessagesPerSecond = original.ShowMessagesPerSecond; } } [HarmonyPatch(typeof(GameManager))] internal static class GameManagerPatches { internal static readonly MethodInfo method_SetMaxPlayers = typeof(GameManager).GetMethod("SetMaxPlayers"); [HarmonyPrepare] private static void Patch() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (RoboUnion.UseV04MaxPlayersLogic) { HarmonyMethod val = new HarmonyMethod(new Action<GameManager>(SetMaxPlayers_Postfix).Method); RoboUnion.Instance.Harmony.Patch((MethodBase)method_SetMaxPlayers, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Awake_Postfix(GameManager __instance) { if (RoboUnion.ConfigModel.MaxPlayers.Value > 0) { __instance.SetMaxPlayersSafe(RoboUnion.ConfigModel.MaxPlayers.Value); } } private static void SetMaxPlayers_Postfix(GameManager __instance) { if (SemiFunc.IsMasterClient() && PhotonNetwork.CurrentRoom != null) { RoboUnion.Logger.LogInfo((object)$"Photon room MaxPlayers changed to {PhotonNetwork.CurrentRoom.MaxPlayers}"); } } public static void SetMaxPlayersSafe(this GameManager __instance, int target) { if (RoboUnion.UseV04MaxPlayersLogic) { SetMaxPlayersUnsafe(__instance, target); } static void SetMaxPlayersUnsafe(GameManager __instance, int target) { __instance.maxPlayersPhoton = target; __instance.SetMaxPlayers(target); } } } [HarmonyPatch(typeof(NetworkConnect))] internal static class NetworkConnectPatches { public static int? PhotonServerPlayerLimit { get; private set; } [HarmonyPrepare] private static void Patch() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(NetworkConnect), "OnCreateRoomFailed", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(NetworkConnect), "OnJoinRoomFailed", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(NetworkConnect), "TryJoiningRoom", (Type[])null, (Type[])null); if (!RoboUnion.UseV04MaxPlayersLogic) { HarmonyMethod val = ((!methodInfo.GetParameters().Any((ParameterInfo x) => x.Name == "cause")) ? new HarmonyMethod(new <>A{00000008}<short, string>(OnCreateRoomFailed_Prefix).Method) : new HarmonyMethod(new <>A{00000008}<short, string>(OnCreateRoomFailed_Prefix_v0_1_2_22).Method)); RoboUnion.Instance.Harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); RoboUnion.Instance.Harmony.Patch((MethodBase)methodInfo2, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyMethod val2 = new HarmonyMethod(new Func<IEnumerable<CodeInstruction>, IEnumerable<CodeInstruction>>(TryJoiningRoom_Transpiler).Method); RoboUnion.Instance.Harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null); } } [HarmonyPostfix] [HarmonyPatch("OnCreatedRoom")] private static void OnCreatedRoom_Postfix() { RoboUnion.Logger.LogInfo((object)$"Photon room created. MaxPlayers = {PhotonNetwork.CurrentRoom.MaxPlayers}"); } private static IEnumerable<CodeInstruction> TryJoiningRoom_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_6, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.DeclaredField(typeof(RoomOptions), "MaxPlayers"), (string)null) }); val.ThrowIfInvalid("Could not match 'roomOptions.MaxPlayers = 6'"); val.Set(OpCodes.Call, (object)new Func<int>(TryJoiningRoom_GetMaxPlayers).Method); return val.InstructionEnumeration(); } internal static int TryJoiningRoom_GetMaxPlayers() { int value = RoboUnion.ConfigModel.MaxPlayers.Value; if (PhotonServerPlayerLimit.HasValue && value > PhotonServerPlayerLimit.Value) { return PhotonServerPlayerLimit.Value; } return value; } private static void OnCreateRoomFailed_Prefix(short returnCode, ref string message) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (message.ToLowerInvariant().Contains("max players peer room value is too big")) { int num; try { num = int.Parse(message.Split(':').LastOrDefault()?.Split('.')?.FirstOrDefault() ?? ""); } catch { num = 20; } RoboUnion.Logger.LogWarning((object)$"Max players exceeds current Photon servers limit. Temporarily limting players to {num}"); PhotonServerPlayerLimit = num; message += $"\n<color=#{XColor.ToHexString(new Color(1f, 0.594f, 0f))}>RoboUnion max players limited to {num} for this session.</color>"; } } private static void OnCreateRoomFailed_Prefix_v0_1_2_22(short returnCode, ref string cause) { OnCreateRoomFailed_Prefix(returnCode, ref cause); } } [HarmonyPatch] internal class PhotonWatchdog : MonoBehaviour { private static int messageSendRunningCount = 0; private static int messageSendPreviousCount = 0; private static int messageRecieverRunningCount = 0; private static int messageRecieverPreviousCount = 0; private static int messagesRoomEstimate = 0; private static int messagesRoomEstimateMax = 0; private float lastUpdate; private static string lastExceptionMessage = ""; private void Awake() { ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; } private void Update() { if (Time.realtimeSinceStartup - lastUpdate > 1f) { UpdateMessageSample(); EstimateMessages(); lastUpdate = Time.realtimeSinceStartup; } } private void UpdateMessageSample() { messageSendPreviousCount = messageSendRunningCount; messageSendRunningCount = 0; messageRecieverPreviousCount = messageRecieverRunningCount; messageRecieverRunningCount = 0; } private void EstimateMessages() { int num = messageSendPreviousCount + messageRecieverPreviousCount; Room currentRoom = PhotonNetwork.CurrentRoom; messagesRoomEstimate = num * ((currentRoom == null) ? 1 : currentRoom.PlayerCount); if (messagesRoomEstimate > messagesRoomEstimateMax) { messagesRoomEstimateMax = messagesRoomEstimate; RoboUnion.Logger.LogDebug((object)$"New Photon Room Est. Messages/Second Max: {messagesRoomEstimateMax}"); } if (RoboUnion.ConfigModel.LogMessagesPerSecond.Value) { RoboUnion.Logger.LogDebug((object)$"Photon Player Sent Messages/Second: {messageSendPreviousCount}\r\nPhoton Player Sent Reciever Messages/Second: {messageRecieverPreviousCount}\r\nPhoton Room Est. Messages/Second: {messagesRoomEstimate}\r\nPhoton Room Est. Messages/Second Max: {messagesRoomEstimateMax}"); } } private void OnGUI() { if (RoboUnion.ConfigModel.ShowMessagesPerSecond.Value) { GUILayout.Label($"Photon Player Sent Messages/Second: {messageSendPreviousCount}\r\nPhoton Player Sent Reciever Messages/Second: {messageRecieverPreviousCount}\r\nPhoton Room Est. Messages/Second: {messagesRoomEstimate}\r\nPhoton Room Est. Messages/Second Max: {messagesRoomEstimateMax}", Array.Empty<GUILayoutOption>()); } } [HarmonyPostfix] [HarmonyPatch(typeof(PhotonPeer), "SendOperation", new Type[] { typeof(byte), typeof(ParameterDictionary), typeof(SendOptions) })] public static void PhotonPeer_SendOperation_Postfix(bool __result, ParameterDictionary operationParameters) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0044: Invalid comparison between Unknown and I4 try { if (!__result) { return; } messageSendRunningCount++; object obj = default(object); ReceiverGroup val = (ReceiverGroup)((!operationParameters.TryGetValue((byte)246, ref obj) || (!(obj is ReceiverGroup) && !(obj is byte))) ? ((ReceiverGroup)0) : ((ReceiverGroup)obj)); if ((int)val > 1) { if ((int)val == 2) { messageRecieverRunningCount++; } } else { int num = messageRecieverRunningCount; Room currentRoom = PhotonNetwork.CurrentRoom; messageRecieverRunningCount = num + (((currentRoom == null) ? 1 : currentRoom.PlayerCount) - 1); } } catch (Exception ex) { string text = "LoadBalancingPeer_SendOperation_Postfix Exception:\n" + ex.Message + "\n" + ex.StackTrace; if (text != lastExceptionMessage) { RoboUnion.Logger.LogDebug((object)text); lastExceptionMessage = text; } } } } [BepInPlugin("Linkoid.Repo.RoboUnion", "RoboUnion", "0.6")] public class RoboUnion : BaseUnityPlugin { internal static RoboUnion Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; internal static ConfigModel ConfigModel { get; private set; } private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal static bool UseV04MaxPlayersLogic => GameManagerPatches.method_SetMaxPlayers != null; private void Awake() { //IL_0068: 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_006f: Expected O, but got Unknown //IL_0074: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; ConfigModel = new ConfigModel(((BaseUnityPlugin)this).Config); ConfigModel.MaxPlayers.SettingChanged += OnMaxPlayersChanged; if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void Start() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown Logger.LogInfo((object)"Creating PhotonWatchdog"); GameObject val = new GameObject("PhotonWatchdog", new Type[1] { typeof(PhotonWatchdog) }); } private void OnMaxPlayersChanged(object sender, EventArgs args) { int target = ((ConfigModel.MaxPlayers.Value > 0) ? ConfigModel.MaxPlayers.Value : 6); if (Object.op_Implicit((Object)(object)GameManager.instance)) { GameManager.instance.SetMaxPlayersSafe(target); } } } }