diff --git a/NebulaModel/Packets/GameStates/GameStateSaveInfoPacket.cs b/NebulaModel/Packets/GameStates/GameStateSaveInfoPacket.cs new file mode 100644 index 000000000..3c9aec684 --- /dev/null +++ b/NebulaModel/Packets/GameStates/GameStateSaveInfoPacket.cs @@ -0,0 +1,20 @@ +#region + +using NebulaAPI.Packets; + +#endregion + +namespace NebulaModel.Packets.GameStates; + +[HidePacketInDebugLogs] +public class GameStateSaveInfoPacket +{ + public GameStateSaveInfoPacket() { } + + public GameStateSaveInfoPacket(long lastSaveTime) + { + LastSaveTime = lastSaveTime; + } + + public long LastSaveTime { get; set; } +} diff --git a/NebulaNetwork/PacketProcessors/GameStates/GameStateSaveInfoProcessor.cs b/NebulaNetwork/PacketProcessors/GameStates/GameStateSaveInfoProcessor.cs new file mode 100644 index 000000000..3630fdc76 --- /dev/null +++ b/NebulaNetwork/PacketProcessors/GameStates/GameStateSaveInfoProcessor.cs @@ -0,0 +1,20 @@ +#region + +using NebulaAPI.Packets; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.GameStates; +using NebulaWorld.GameStates; + +#endregion + +namespace NebulaNetwork.PacketProcessors.GameStates; + +[RegisterPacketProcessor] +public class GameStateSaveInfoProcessor : PacketProcessor +{ + protected override void ProcessPacket(GameStateSaveInfoPacket packet, NebulaConnection conn) + { + GameStatesManager.LastSaveTime = packet.LastSaveTime; + } +} diff --git a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs index 29a0b5daa..19cb8e1f8 100644 --- a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs @@ -3,7 +3,9 @@ using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; +using NebulaModel.Packets.GameStates; using NebulaModel.Packets.Session; +using NebulaWorld.GameStates; #endregion @@ -74,5 +76,7 @@ protected override void ProcessPacket(GlobalGameDataRequest packet, NebulaConnec conn.SendPacket(new GlobalGameDataResponse( GlobalGameDataResponse.EDataType.Ready, writer.CloseAndGetBytes())); } + + conn.SendPacket(new GameStateSaveInfoPacket(GameStatesManager.LastSaveTime)); } } diff --git a/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs index f446cb062..8026cd430 100644 --- a/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs @@ -1,9 +1,11 @@ #region +using System.Diagnostics.CodeAnalysis; using HarmonyLib; using NebulaModel; -using NebulaNetwork; +using NebulaModel.Packets.GameStates; using NebulaWorld; +using NebulaWorld.GameStates; #endregion @@ -46,6 +48,9 @@ public static void SaveCurrentGame_Postfix() (GameMain.mainPlayer.sandCount, Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount) = ( Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount, GameMain.mainPlayer.sandCount); } + // Update last save time in clients + GameStatesManager.LastSaveTime = GameMain.gameTick; + Multiplayer.Session.Server.SendPacket(new GameStateSaveInfoPacket(GameMain.gameTick)); } [HarmonyPrefix] @@ -66,6 +71,7 @@ public static bool SaveAsLastExit_Prefix() [HarmonyPostfix] [HarmonyPatch(nameof(GameSave.LoadCurrentGame))] + [SuppressMessage("Style", "IDE1006:Naming Styles")] public static void LoadCurrentGame_Postfix(bool __result) { // If loading success, check and correct offset for all inserters @@ -88,5 +94,9 @@ public static void LoadCurrentGame_Postfix(bool __result) } } } + if (Multiplayer.IsActive && Multiplayer.Session.LocalPlayer.IsHost) + { + GameStatesManager.LastSaveTime = GameMain.gameTick; + } } } diff --git a/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs index a2a0ce1b4..b8fc5e827 100644 --- a/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs @@ -6,6 +6,7 @@ using NebulaModel.Packets.Players; using NebulaPatcher.Patches.Transpilers; using NebulaWorld; +using NebulaWorld.GameStates; using UnityEngine; using UnityEngine.UI; @@ -30,6 +31,21 @@ public static void _OnOpen_Prefix(UIEscMenu __instance) SetButtonEnableState(loadGameWindowButton, !Multiplayer.IsActive); } + [HarmonyPostfix] + [HarmonyPatch(nameof(UIEscMenu._OnOpen))] + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] + public static void _OnOpen_Postfix(UIEscMenu __instance) + { + if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) return; + + var timeSinceSave = GameMain.gameTick - GameStatesManager.LastSaveTime; + var second = (int)(timeSinceSave / 60L); + var minute = second / 60; + var hour = minute / 60; + var saveBtnText = "存档时间".Translate() + $" {hour}h{minute % 60}m{second % 60}s ago"; + __instance.button2Text.text = saveBtnText; + } + [HarmonyPrefix] [HarmonyPatch(nameof(UIEscMenu.OnButton5Click))] public static void OnButton5Click_Prefix() diff --git a/NebulaWorld/GameStates/GameStatesManager.cs b/NebulaWorld/GameStates/GameStatesManager.cs index f630b6b23..a8d655c30 100644 --- a/NebulaWorld/GameStates/GameStatesManager.cs +++ b/NebulaWorld/GameStates/GameStatesManager.cs @@ -19,6 +19,7 @@ public class GameStatesManager : IDisposable public static long RealGameTick => GameMain.gameTick; public static float RealUPS => (float)FPSController.currentUPS; public static string ImportedSaveName { get; set; } + public static long LastSaveTime { get; set; } public static GameDesc NewGameDesc { get; set; } public static int FragmentSize { get; set; } @@ -33,7 +34,7 @@ public class GameStatesManager : IDisposable public void Dispose() { - FragmentSize = 0; + LastSaveTime = FragmentSize = 0; SandboxToolsEnabled = false; HistoryBinaryData = null; GalacticTransportBinaryData = null;