diff --git a/Torch.API/ITorchBase.cs b/Torch.API/ITorchBase.cs index e83aa63..e550fe4 100644 --- a/Torch.API/ITorchBase.cs +++ b/Torch.API/ITorchBase.cs @@ -25,6 +25,7 @@ namespace Torch.API bool IsOnGameThread(); void Start(); void Stop(); + void Save(long callerId); void Init(); T GetManager() where T : class, IManager; } diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs index a41eed5..3e9934d 100644 --- a/Torch.Server/TorchServer.cs +++ b/Torch.Server/TorchServer.cs @@ -221,5 +221,35 @@ namespace Torch.Server _stopHandle.Set(); State = ServerState.Stopped; } + + public override void Save(long callerId) + { + base.SaveGameAsync((statusCode) => SaveCompleted(statusCode, callerId)); + } + + private void SaveCompleted(SaveGameStatus statusCode, long callerId) + { + switch (statusCode) + { + case SaveGameStatus.Success: + Log.Info("Save completed."); + Multiplayer.SendMessage("Saved game.", playerId: callerId); + break; + case SaveGameStatus.SaveInProgress: + Log.Error("Save failed, a save is already in progress."); + Multiplayer.SendMessage("Save failed, a save is already in progress.", playerId: callerId, font: MyFontEnum.Red); + break; + case SaveGameStatus.GameNotReady: + Log.Error("Save failed, game was not ready."); + Multiplayer.SendMessage("Save failed, game was not ready.", playerId: callerId, font: MyFontEnum.Red); + break; + case SaveGameStatus.TimedOut: + Log.Error("Save failed, save timed out."); + Multiplayer.SendMessage("Save failed, save timed out.", playerId: callerId, font: MyFontEnum.Red); + break; + default: + break; + } + } } } diff --git a/Torch/Commands/TorchCommands.cs b/Torch/Commands/TorchCommands.cs index 08cae6b..378d173 100644 --- a/Torch/Commands/TorchCommands.cs +++ b/Torch/Commands/TorchCommands.cs @@ -67,5 +67,12 @@ namespace Torch.Commands Context.Respond("Stopping server."); Context.Torch.Stop(); } + + [Command("save", "Saves the game.")] + public void Save() + { + Context.Respond("Saving game."); + Context.Torch.Save(Context.Player?.IdentityId ?? 0); + } } -} +} \ No newline at end of file diff --git a/Torch/TorchBase.cs b/Torch/TorchBase.cs index 7f3f471..e167cf0 100644 --- a/Torch/TorchBase.cs +++ b/Torch/TorchBase.cs @@ -31,6 +31,14 @@ using VRage.Utils; namespace Torch { + public enum SaveGameStatus : byte + { + Success = 0, + SaveInProgress = 1, + GameNotReady = 2, + TimedOut = 3 + }; + /// /// Base class for code shared between the Torch client and server. /// @@ -109,10 +117,19 @@ namespace Torch return Thread.CurrentThread.ManagedThreadId == MySandboxGame.Static.UpdateThread.ManagedThreadId; } - public async Task SaveGameAsync() + public async Task SaveGameAsync(Action callback) { Log.Info("Saving game"); - if (MySandboxGame.IsGameReady && !MyAsyncSaving.InProgress && Sync.IsServer && !(MySession.Static.LocalCharacter?.IsDead ?? true)) + + if (!MySandboxGame.IsGameReady) + { + callback(SaveGameStatus.GameNotReady); + } + else if(MyAsyncSaving.InProgress) + { + callback(SaveGameStatus.SaveInProgress); + } + else { using (var e = new AutoResetEvent(false)) { @@ -125,17 +142,13 @@ namespace Torch await Task.Run(() => { if (e.WaitOne(60000)) - return; - - Log.Error("Save failed!"); - Multiplayer.SendMessage("Save timed out!", "Error"); + callback(SaveGameStatus.Success); + return; + + callback(SaveGameStatus.TimedOut); }).ConfigureAwait(false); } } - else - { - Log.Error("Cannot save"); - } } #region Game Actions @@ -279,6 +292,11 @@ namespace Torch pluginList.Add(this); } + public virtual void Save(long callerId) + { + + } + public virtual void Start() {