Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate-beta"
Decompiled source of MultiplayerEnhanced v1.0.1
MultiplayerEnhanced.dll
Decompiled 6 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using Il2Cpp; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Networking; using Il2CppScheduleOne.UI.Multiplayer; using Il2CppSteamworks; using Il2CppSystem; using Il2CppTMPro; using MelonLoader; using Microsoft.CodeAnalysis; using MultiplayerEnhanced; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "MultiplayerEnhanced", "1.0.0", "goustkor", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("MultiplayerEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MultiplayerEnhanced")] [assembly: AssemblyTitle("MultiplayerEnhanced")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MultiplayerEnhanced { public class Core : MelonMod { [HarmonyPatch(typeof(LobbyInterface), "Awake")] public static class LobbyInterface_Awake_PostfixPatch { private static void Postfix(LobbyInterface __instance) { if (!((Object)(object)__instance.Lobby == (Object)null)) { __instance.Lobby.onLobbyChange = Action.op_Implicit((Action)delegate { AccessTools.Method(typeof(LobbyInterface), "UpdateButtons", (Type[])null, (Type[])null).Invoke(__instance, null); AccessTools.Method(typeof(LobbyInterface), "UpdatePlayers", (Type[])null, (Type[])null).Invoke(__instance, null); ((TMP_Text)__instance.LobbyTitle).text = "Lobby (" + __instance.Lobby.PlayerCount + "/" + maxPlayers + ")"; }); } } } [HarmonyPatch(typeof(LobbyInterface), "UpdateButtons")] public class UpdateButtonsPatch { private static bool Prefix(LobbyInterface __instance) { ((Component)__instance.InviteButton).gameObject.SetActive(__instance.Lobby.IsHost && __instance.Lobby.PlayerCount < maxPlayers); ((Component)__instance.LeaveButton).gameObject.SetActive(!__instance.Lobby.IsHost); return false; } } [CompilerGenerated] private sealed class <WaitForLobby>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Lobby <lobby>5__1; private LobbyInterface <lobbyInterface>5__2; private Transform <entries>5__3; private Button <inviteButton>5__4; private UnityAction <acao>5__5; private Transform <template>5__6; private int <i>5__7; private GameObject <newEntry>5__8; private int <newIndex>5__9; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForLobby>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <lobby>5__1 = null; <lobbyInterface>5__2 = null; <entries>5__3 = null; <inviteButton>5__4 = null; <acao>5__5 = null; <template>5__6 = null; <newEntry>5__8 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ((MelonBase)<>4__this).LoggerInstance.Msg("Waiting for lobby..."); goto IL_005d; case 1: <>1__state = -1; goto IL_005d; case 2: { <>1__state = -1; break; } IL_005d: if ((Object)(object)Singleton<Lobby>.Instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } <lobby>5__1 = Singleton<Lobby>.Instance; if (!SteamManager.Initialized) { ((Component)<lobby>5__1).gameObject.SetActive(false); <>2__current = null; <>1__state = 2; return true; } break; } <lobbyInterface>5__2 = Singleton<LobbyInterface>.Instance; <>4__this.harmony.PatchAll(); <entries>5__3 = ((Component)((Component)<lobby>5__1).GetComponentInChildren<GridLayoutGroup>()).transform; if (<entries>5__3.childCount > 1) { <template>5__6 = <entries>5__3.GetChild(1); <i>5__7 = 1; while (<i>5__7 < maxPlayers - 4) { <newEntry>5__8 = Object.Instantiate<GameObject>(((Component)<template>5__6).gameObject, <entries>5__3); <newIndex>5__9 = <entries>5__3.childCount - 1; ((Object)<newEntry>5__8).name = ((Object)((Component)<template>5__6).gameObject).name + " (" + <newIndex>5__9 + ")"; <newEntry>5__8 = null; <i>5__7++; } <template>5__6 = null; } <lobby>5__1.Players = Il2CppStructArray<CSteamID>.op_Implicit((CSteamID[])(object)new CSteamID[maxPlayers]); ((TMP_Text)<lobbyInterface>5__2.LobbyTitle).text = "Lobby (" + <lobby>5__1.PlayerCount + "/" + maxPlayers + ")"; <entries>5__3.GetChild(4).SetSiblingIndex(maxPlayers); <inviteButton>5__4 = ((Component)<entries>5__3.GetChild(0)).GetComponent<Button>(); ((UnityEventBase)<inviteButton>5__4.onClick).RemoveAllListeners(); <acao>5__5 = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)new Action(<>4__this.Invite)); ((UnityEvent)<inviteButton>5__4.onClick).AddListener(<acao>5__5); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <tryopeninvite>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Lobby <lobby>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <tryopeninvite>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <lobby>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <lobby>5__1 = Singleton<Lobby>.Instance; break; case 1: <>1__state = -1; break; } if (<lobby>5__1.LobbyID == 0) { <>2__current = null; <>1__state = 1; return true; } SteamFriends.ActivateGameOverlayInviteDialog(<lobby>5__1.LobbySteamID); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static int maxPlayers = 20; public Harmony harmony = new Harmony("goustkor.MultiplayerEnhanced"); public override void OnInitializeMelon() { ((MelonBase)this).LoggerInstance.Msg("Initialized."); } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (!(sceneName != "Menu")) { ((MelonBase)this).LoggerInstance.Msg("Scene was initialized: " + sceneName); MelonCoroutines.Start(WaitForLobby()); } } [IteratorStateMachine(typeof(<WaitForLobby>d__4))] private IEnumerator WaitForLobby() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForLobby>d__4(0) { <>4__this = this }; } private void Invite() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (SteamManager.Initialized) { if (!Singleton<Lobby>.Instance.IsInLobby) { PlayerPrefs.SetInt("InviteHintShown", 1); Singleton<LobbyInterface>.Instance.InviteHint.SetActive(false); SteamMatchmaking.CreateLobby((ELobbyType)0, maxPlayers); } MelonCoroutines.Start(tryopeninvite()); } } [IteratorStateMachine(typeof(<tryopeninvite>d__6))] private IEnumerator tryopeninvite() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <tryopeninvite>d__6(0) { <>4__this = this }; } } }