Added async /save command for admins+ and server console.

Redesigned TorchBase.SaveGameAsync to take a callback function for error/success handling. Also removed local host checks as we are hosting a dedicated server.
This commit is contained in:
Alexander Qvist-Hellum
2017-07-06 16:18:10 +02:00
parent 79fe6a08ab
commit 1251b945bc
4 changed files with 67 additions and 11 deletions

View File

@@ -25,6 +25,7 @@ namespace Torch.API
bool IsOnGameThread(); bool IsOnGameThread();
void Start(); void Start();
void Stop(); void Stop();
void Save(long callerId);
void Init(); void Init();
T GetManager<T>() where T : class, IManager; T GetManager<T>() where T : class, IManager;
} }

View File

@@ -221,5 +221,35 @@ namespace Torch.Server
_stopHandle.Set(); _stopHandle.Set();
State = ServerState.Stopped; 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;
}
}
} }
} }

View File

@@ -67,5 +67,12 @@ namespace Torch.Commands
Context.Respond("Stopping server."); Context.Respond("Stopping server.");
Context.Torch.Stop(); Context.Torch.Stop();
} }
[Command("save", "Saves the game.")]
public void Save()
{
Context.Respond("Saving game.");
Context.Torch.Save(Context.Player?.IdentityId ?? 0);
}
} }
} }

View File

@@ -31,6 +31,14 @@ using VRage.Utils;
namespace Torch namespace Torch
{ {
public enum SaveGameStatus : byte
{
Success = 0,
SaveInProgress = 1,
GameNotReady = 2,
TimedOut = 3
};
/// <summary> /// <summary>
/// Base class for code shared between the Torch client and server. /// Base class for code shared between the Torch client and server.
/// </summary> /// </summary>
@@ -109,10 +117,19 @@ namespace Torch
return Thread.CurrentThread.ManagedThreadId == MySandboxGame.Static.UpdateThread.ManagedThreadId; return Thread.CurrentThread.ManagedThreadId == MySandboxGame.Static.UpdateThread.ManagedThreadId;
} }
public async Task SaveGameAsync() public async Task SaveGameAsync(Action<SaveGameStatus> callback)
{ {
Log.Info("Saving game"); 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)) using (var e = new AutoResetEvent(false))
{ {
@@ -125,17 +142,13 @@ namespace Torch
await Task.Run(() => await Task.Run(() =>
{ {
if (e.WaitOne(60000)) if (e.WaitOne(60000))
return; callback(SaveGameStatus.Success);
return;
Log.Error("Save failed!"); callback(SaveGameStatus.TimedOut);
Multiplayer.SendMessage("Save timed out!", "Error");
}).ConfigureAwait(false); }).ConfigureAwait(false);
} }
} }
else
{
Log.Error("Cannot save");
}
} }
#region Game Actions #region Game Actions
@@ -279,6 +292,11 @@ namespace Torch
pluginList.Add(this); pluginList.Add(this);
} }
public virtual void Save(long callerId)
{
}
public virtual void Start() public virtual void Start()
{ {