From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Sat, 16 Sep 2023 11:46:12 +0000 (+1200)
Subject: Fix replay recording temporary paths not supporting subdirectories (#19887)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=7d9693d9761a1c38e06151144ce8addf0c397263;p=space-station-14.git
Fix replay recording temporary paths not supporting subdirectories (#19887)
---
diff --git a/Content.IntegrationTests/Tests/Replays/ReplayTests.cs b/Content.IntegrationTests/Tests/Replays/ReplayTests.cs
new file mode 100644
index 0000000000..7e2d3da4b6
--- /dev/null
+++ b/Content.IntegrationTests/Tests/Replays/ReplayTests.cs
@@ -0,0 +1,56 @@
+using Content.Server.GameTicking;
+using Content.Shared.CCVar;
+using Robust.Shared;
+using Robust.Shared.Replays;
+
+namespace Content.IntegrationTests.Tests.Replays;
+
+[TestFixture]
+public sealed class ReplayTests
+{
+ ///
+ /// Simple test that just makes sure that automatic replay recording on round restarts works without any issues.
+ ///
+ [Test]
+ public async Task AutoRecordReplayTest()
+ {
+ var settings = new PoolSettings {DummyTicker = false};
+ await using var pair = await PoolManager.GetServerClient(settings);
+ var server = pair.Server;
+
+ Assert.That(server.CfgMan.GetCVar(CVars.ReplayServerRecordingEnabled), Is.False);
+ var recordMan = server.ResolveDependency();
+ Assert.That(recordMan.IsRecording, Is.False);
+
+ // Setup cvars.
+ var autoRec = server.CfgMan.GetCVar(CCVars.ReplayAutoRecord);
+ var autoRecName = server.CfgMan.GetCVar(CCVars.ReplayAutoRecordName);
+ var tempDir = server.CfgMan.GetCVar(CCVars.ReplayAutoRecordTempDir);
+ server.CfgMan.SetCVar(CVars.ReplayServerRecordingEnabled, true);
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecord, true);
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecordTempDir, "/a/b/");
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecordName, $"c/d/{autoRecName}");
+
+ // Restart the round a few times
+ var ticker = server.System();
+ await server.WaitPost(() => ticker.RestartRound());
+ await pair.RunTicksSync(25);
+ Assert.That(recordMan.IsRecording, Is.True);
+ await server.WaitPost(() => ticker.RestartRound());
+ await pair.RunTicksSync(25);
+ Assert.That(recordMan.IsRecording, Is.True);
+
+ // Reset cvars
+ server.CfgMan.SetCVar(CVars.ReplayServerRecordingEnabled, false);
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecord, autoRec);
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecordTempDir, tempDir);
+ server.CfgMan.SetCVar(CCVars.ReplayAutoRecordName, autoRecName);
+
+ // Restart the round again to disable the current recording.
+ await server.WaitPost(() => ticker.RestartRound());
+ await pair.RunTicksSync(25);
+ Assert.That(recordMan.IsRecording, Is.False);
+
+ await pair.CleanReturnAsync();
+ }
+}
diff --git a/Content.Server/GameTicking/GameTicker.Replays.cs b/Content.Server/GameTicking/GameTicker.Replays.cs
index 3254fb840d..42e2de0228 100644
--- a/Content.Server/GameTicking/GameTicker.Replays.cs
+++ b/Content.Server/GameTicking/GameTicker.Replays.cs
@@ -72,13 +72,14 @@ public sealed partial class GameTicker
if (data.State is not ReplayRecordState state)
return;
- if (state.MoveToPath != null)
- {
- _sawmillReplays.Info($"Moving replay into final position: {state.MoveToPath}");
+ if (state.MoveToPath == null)
+ return;
- _taskManager.BlockWaitOnTask(_replays.WaitWriteTasks());
- data.Directory.Rename(data.Path, state.MoveToPath.Value);
- }
+ _sawmillReplays.Info($"Moving replay into final position: {state.MoveToPath}");
+ _taskManager.BlockWaitOnTask(_replays.WaitWriteTasks());
+ DebugTools.Assert(!_replays.IsWriting());
+ data.Directory.CreateDir(state.MoveToPath.Value.Directory);
+ data.Directory.Rename(data.Path, state.MoveToPath.Value);
}
private ResPath GetAutoReplayPath()
diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs
index 19464a4fc3..a0cde055ba 100644
--- a/Content.Shared/CCVar/CCVars.cs
+++ b/Content.Shared/CCVar/CCVars.cs
@@ -1776,6 +1776,7 @@ namespace Content.Shared.CCVar
///
/// Path that, if provided, automatic replays are initially recorded in.
/// When the recording is done, the file is moved into its final destination.
+ /// Unless this path is rooted, it will be relative to .
///
public static readonly CVarDef ReplayAutoRecordTempDir =
CVarDef.Create("replay.auto_record_temp_dir", "", CVar.SERVERONLY);