diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectSavefile.cs b/OpenDreamRuntime/Objects/Types/DreamObjectSavefile.cs index e73e49498b..43f7f5ea30 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectSavefile.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectSavefile.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; @@ -83,9 +83,9 @@ public sealed class DreamFileValue : DreamJsonValue { public DreamResource Resource = default!; /// - /// The current savefile data holder + /// The current savefile data holder - the root of the savefile tree /// - public DreamJsonValue Savefile = default!; + private DreamJsonValue _rootNode = default!; /// /// The current savefile' working dir. This could be a generic primitive @@ -130,11 +130,11 @@ public override void Initialize(DreamProcArguments args) { var data = Resource.ReadAsString(); if (!string.IsNullOrEmpty(data)) { - CurrentDir = Savefile = JsonSerializer.Deserialize(data); - SavefileDirectories.Add(filename, Savefile); + CurrentDir = _rootNode = JsonSerializer.Deserialize(data); + SavefileDirectories.Add(filename, _rootNode); } else { - CurrentDir = Savefile = new DreamJsonValue(); - SavefileDirectories.Add(filename, Savefile); + CurrentDir = _rootNode = new DreamJsonValue(); + SavefileDirectories.Add(filename, _rootNode); //create the file immediately Flush(); } @@ -251,20 +251,22 @@ public void Close() { public void Flush() { Resource.Clear(); - Resource.Output(new DreamValue(JsonSerializer.Serialize(Savefile))); + Resource.Output(new DreamValue(JsonSerializer.Serialize(_rootNode))); } /// /// Attempts to go to said path relative to CurrentPath (you still have to set CurrentDir) /// private DreamJsonValue SeekTo(string to) { - DreamJsonValue tempDir = Savefile; + DreamJsonValue tempDir = _rootNode; var searchPath = new DreamPath(_currentPath).AddToPath(to).PathString; //relative path if(to.StartsWith("/")) //absolute path searchPath = to; foreach (var path in searchPath.Split("/")) { + if(path == string.Empty) + continue; if (!tempDir.TryGetValue(path, out var newDir)) { newDir = tempDir[path] = new DreamJsonValue(); } @@ -291,13 +293,19 @@ public void SetSavefileValue(string? index, DreamValue value) { var pathArray = index.Split("/"); if (pathArray.Length == 1) { - CurrentDir[index] = SerializeDreamValue(value); - _savefilesToFlush.Add(this); - return; + var newValue = SerializeDreamValue(value); + if(CurrentDir.TryGetValue(index, out var oldValue)) { + foreach(var key in oldValue.Keys) { + newValue[key] = oldValue[key]; + } + } + CurrentDir[index] = newValue; + } else { + string oldPath = CurrentPath; + CurrentPath = new DreamPath(index).AddToPath("../").PathString; //get the parent of the target path + SetSavefileValue(pathArray[pathArray.Length - 1], value); + CurrentPath = oldPath; } - - // go to said dir, seek down and get the last path BEFORE we index the thing - SeekTo(new DreamPath(index).AddToPath("../").PathString)[pathArray[pathArray.Length - 1]] = SerializeDreamValue(value); _savefilesToFlush.Add(this); }