Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of MultiplayerEnhanced v1.0.1
MultiplayerEnhanced.dll
Decompiled 10 months 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 }; } } }