mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Add support for including map/game saves in replays. (#6189)
* Improve map serialization error logging * Prevent remove children of erroring entities * better logging * Improve error tolerance * Even more exception tolerance * missing ! * Add WriteYaml and WriteObject to IReplayFileWriter * Add MapLoaderSystem.TrySaveAllEntities() * On second thought, WriteObject will just be abused * I forgot to commit * Add default implementation to avoid breaking changes * release notes * fix merge issues --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
@@ -2,11 +2,15 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Replays;
|
||||
|
||||
@@ -202,6 +206,25 @@ public interface IReplayFileWriter
|
||||
ResPath path,
|
||||
ReadOnlyMemory<byte> bytes,
|
||||
CompressionLevel compressionLevel = CompressionLevel.Optimal);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a yaml document into a file in the replay.
|
||||
/// </summary>
|
||||
/// <param name="path">The file path to write to.</param>
|
||||
/// <param name="yaml">The yaml document to write to the file.</param>
|
||||
/// <param name="compressionLevel">How much to compress the file.</param>
|
||||
void WriteYaml(
|
||||
ResPath path,
|
||||
YamlDocument yaml,
|
||||
CompressionLevel compressionLevel = CompressionLevel.Optimal)
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
using var writer = new StreamWriter(memStream);
|
||||
var yamlStream = new YamlStream {yaml};
|
||||
yamlStream.Save(new YamlMappingFix(new Emitter(writer)), false);
|
||||
writer.Flush();
|
||||
WriteBytes(path, memStream.AsMemory(), compressionLevel);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,22 +26,30 @@ internal abstract partial class SharedReplayRecordingManager
|
||||
// and even then not for much longer than a couple hundred ms at most.
|
||||
private readonly List<Task> _finalizingWriteTasks = new();
|
||||
|
||||
private void WriteYaml(RecordingState state, ResPath path, YamlDocument data)
|
||||
private void WriteYaml(
|
||||
RecordingState state,
|
||||
ResPath path,
|
||||
YamlDocument data,
|
||||
CompressionLevel level = CompressionLevel.Optimal)
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
using var writer = new StreamWriter(memStream);
|
||||
var yamlStream = new YamlStream { data };
|
||||
yamlStream.Save(new YamlMappingFix(new Emitter(writer)), false);
|
||||
writer.Flush();
|
||||
WriteBytes(state, path, memStream.AsMemory());
|
||||
WriteBytes(state, path, memStream.AsMemory(), level);
|
||||
}
|
||||
|
||||
private void WriteSerializer<T>(RecordingState state, ResPath path, T obj)
|
||||
private void WriteSerializer<T>(
|
||||
RecordingState state,
|
||||
ResPath path,
|
||||
T obj,
|
||||
CompressionLevel level = CompressionLevel.Optimal)
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
_serializer.SerializeDirect(memStream, obj);
|
||||
|
||||
WriteBytes(state, path, memStream.AsMemory());
|
||||
WriteBytes(state, path, memStream.AsMemory(), level);
|
||||
}
|
||||
|
||||
private void WritePooledBytes(
|
||||
|
||||
@@ -375,6 +375,11 @@ internal abstract partial class SharedReplayRecordingManager : IReplayRecordingM
|
||||
private void WriteFinalMetadata(RecordingState recState)
|
||||
{
|
||||
var yamlMetadata = new MappingDataNode();
|
||||
|
||||
// TODO REPLAYS
|
||||
// Why are these separate events?
|
||||
// I assume it was for backwards compatibility / avoiding breaking changes?
|
||||
// But eventually RecordingStopped2 will probably be renamed and there'll just be more breaking changes.
|
||||
RecordingStopped?.Invoke(yamlMetadata);
|
||||
RecordingStopped2?.Invoke(new ReplayRecordingStopped
|
||||
{
|
||||
@@ -552,6 +557,12 @@ internal abstract partial class SharedReplayRecordingManager : IReplayRecordingM
|
||||
manager.WriteBytes(state, path, bytes, compressionLevel);
|
||||
}
|
||||
|
||||
void IReplayFileWriter.WriteYaml(ResPath path, YamlDocument document, CompressionLevel compressionLevel)
|
||||
{
|
||||
CheckDisposed();
|
||||
manager.WriteYaml(state, path, document, compressionLevel);
|
||||
}
|
||||
|
||||
private void CheckDisposed()
|
||||
{
|
||||
if (state.Done)
|
||||
|
||||
Reference in New Issue
Block a user