diff --git a/NebulaHost/MultiplayerHostSession.cs b/NebulaHost/MultiplayerHostSession.cs index c8c401ab2..8de44b0f5 100644 --- a/NebulaHost/MultiplayerHostSession.cs +++ b/NebulaHost/MultiplayerHostSession.cs @@ -43,7 +43,6 @@ public void StartServer(int port, bool loadSaveFile = false) { SaveManager.LoadServerData(); } - SaveManager.SaveOnExit = true; PacketProcessor = new NetPacketProcessor(); StatisticsManager = new StatisticsManager(); diff --git a/NebulaPatcher/NebulaPatcher.csproj b/NebulaPatcher/NebulaPatcher.csproj index f6d638a5e..96a40c5a2 100644 --- a/NebulaPatcher/NebulaPatcher.csproj +++ b/NebulaPatcher/NebulaPatcher.csproj @@ -66,6 +66,7 @@ + diff --git a/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs index 41718a412..0ed19b0b4 100644 --- a/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs @@ -11,18 +11,13 @@ class GameSave_Patch [HarmonyPatch("SaveCurrentGame")] public static bool SaveCurrentGame_Prefix(string saveName) { - if (SaveManager.SaveOnExit || SimulatedWorld.Initialized && LocalPlayer.IsMasterClient) + if (SimulatedWorld.Initialized && LocalPlayer.IsMasterClient) { SaveManager.SaveServerData(saveName); - SaveManager.SaveOnExit = false; } - if (SimulatedWorld.Initialized && !LocalPlayer.IsMasterClient) - { - return false; - } - - return true; + // Only save if in single player or if you are the host + return (!SimulatedWorld.Initialized && !SimulatedWorld.ExitingMultiplayerSession) || LocalPlayer.IsMasterClient; } [HarmonyPrefix] @@ -32,10 +27,11 @@ public static void LoadCurrentGame_Prefix(string saveName) SaveManager.SetLastSave(saveName); } + [HarmonyPrefix] [HarmonyPatch("AutoSave")] public static bool AutoSave_Prefix() { - //Do not trigger autosave for the clients in multiplayer + // Only save if in single player or if you are the host return !SimulatedWorld.Initialized || LocalPlayer.IsMasterClient; } @@ -43,8 +39,8 @@ public static bool AutoSave_Prefix() [HarmonyPatch("SaveAsLastExit")] public static bool SaveAsLastExit_Prefix() { - //Do not trigger autosave for the clients in multiplayer - return !SimulatedWorld.Initialized || LocalPlayer.IsMasterClient; + // Only save if in single player or if you are the host + return (!SimulatedWorld.Initialized && !SimulatedWorld.ExitingMultiplayerSession) || LocalPlayer.IsMasterClient; } } } diff --git a/NebulaPatcher/Patches/Dynamic/UIAutoSave_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIAutoSave_Patch.cs new file mode 100644 index 000000000..f4688a6df --- /dev/null +++ b/NebulaPatcher/Patches/Dynamic/UIAutoSave_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using NebulaModel.Logger; +using NebulaWorld; +using UnityEngine; + +namespace NebulaPatcher.Patches.Dynamic +{ + [HarmonyPatch(typeof(UIAutoSave))] + class UIAutoSave_Patch + { + [HarmonyPostfix] + [HarmonyPatch("_OnOpen")] + public static void _OnOpen_Postfix(UIAutoSave __instance) + { + // Hide AutoSave failed message on clients, since client cannot save in multiplayer + CanvasGroup contentCanvas = AccessTools.Field(__instance.GetType(), "contentCanvas").GetValue(__instance) as CanvasGroup; + contentCanvas?.gameObject.SetActive(!SimulatedWorld.Initialized || LocalPlayer.IsMasterClient); + Log.Warn($"UIAutoSave active: {contentCanvas?.gameObject.activeSelf}"); + } + + [HarmonyPrefix] + [HarmonyPatch("_OnLateUpdate")] + public static bool _OnLateUpdate_Prefix() + { + return !SimulatedWorld.Initialized || LocalPlayer.IsMasterClient; + } + } +} diff --git a/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs index 7735f08b4..54bdcfba3 100644 --- a/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs @@ -16,8 +16,16 @@ class UIEscMenu_Patch [HarmonyPrefix] [HarmonyPatch("_OnOpen")] - public static void _OnOpen_Prefix() + public static void _OnOpen_Prefix(UIEscMenu __instance) { + // Disable save game button if you are a client in a multiplayer session + Button saveGameWindowButton = AccessTools.Field(typeof(UIEscMenu), "button2").GetValue(__instance) as Button; + SetButtonEnableState(saveGameWindowButton, !SimulatedWorld.Initialized || LocalPlayer.IsMasterClient); + + // Disable load game button if in a multiplayer session + Button loadGameWindowButton = AccessTools.Field(typeof(UIEscMenu), "button3").GetValue(__instance) as Button; + SetButtonEnableState(loadGameWindowButton, !SimulatedWorld.Initialized); + // If we are in a multiplayer game already make sure to hide the host game button if (SimulatedWorld.Initialized) { @@ -64,10 +72,18 @@ private static void OnHostCurrentGameClick() var session = NebulaBootstrapper.Instance.CreateMultiplayerHostSession(); session.StartServer(port, true); - // Manually call the OnGameLoadCompleted here since we are already in a game. + // Manually call the OnGameLoadCompleted manually since we are already in a game. SimulatedWorld.OnGameLoadCompleted(); GameMain.Resume(); } + + private static void SetButtonEnableState(Button button, bool enable) + { + ColorBlock buttonColors = button.colors; + buttonColors.disabledColor = new Color(1f, 1f, 1f, 0.15f); + button.interactable = enable; + button.colors = buttonColors; + } } } diff --git a/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs index b0868a270..a44639078 100644 --- a/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs @@ -2,6 +2,7 @@ using NebulaModel; using NebulaModel.Logger; using NebulaPatcher.MonoBehaviours; +using NebulaWorld; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; @@ -19,6 +20,8 @@ class UIMainMenu_Patch [HarmonyPatch("_OnOpen")] public static void _OnOpen_Postfix() { + SimulatedWorld.ExitingMultiplayerSession = false; + GameObject overlayCanvas = GameObject.Find("Overlay Canvas"); if (overlayCanvas == null) { diff --git a/NebulaWorld/LocalPlayer.cs b/NebulaWorld/LocalPlayer.cs index 188c9f34f..065e84f29 100644 --- a/NebulaWorld/LocalPlayer.cs +++ b/NebulaWorld/LocalPlayer.cs @@ -63,6 +63,7 @@ public static void LeaveGame() PendingFactories.Clear(); IsMasterClient = false; SimulatedWorld.Clear(); + SimulatedWorld.ExitingMultiplayerSession = true; if (!UIRoot.instance.backToMainMenu) { diff --git a/NebulaWorld/SimulatedWorld.cs b/NebulaWorld/SimulatedWorld.cs index d033d6d2e..8b71cfbdf 100644 --- a/NebulaWorld/SimulatedWorld.cs +++ b/NebulaWorld/SimulatedWorld.cs @@ -24,12 +24,14 @@ public static class SimulatedWorld public static bool Initialized { get; private set; } public static bool IsGameLoaded { get; private set; } public static bool IsPlayerJoining { get; set; } + public static bool ExitingMultiplayerSession { get; set; } public static void Initialize() { FactoryManager.Initialize(); remotePlayersModels = new Dictionary(); Initialized = true; + ExitingMultiplayerSession = false; } ///