using VRage.ObjectBuilders; using VRage.ObjectBuilders.Private; namespace SpaceEngineersBlueprintEditor.SpaceEngineersCore; public class SpaceEngineerDefinitions { public static T Load(string path) where T : MyObjectBuilder_Base { MyObjectBuilderSerializerKeen.DeserializeXML(path, out T objectBuilder); return objectBuilder; } public static string Serialize(MyObjectBuilder_Base item) where T : MyObjectBuilder_Base { using var outStream = new MemoryStream(); if (MyObjectBuilderSerializerKeen.SerializeXML(outStream, item)) { outStream.Position = 0; var streamReader = new StreamReader(outStream); return streamReader.ReadToEnd(); } return string.Empty; } /// /// Atomically saves an object builder as an uncompressed SBC file. When the /// destination already exists, its previous contents are retained as sbcB5. /// public static void Save(string path, MyObjectBuilder_Base item) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentException("A blueprint path is required.", nameof(path)); } if (item is null) { throw new ArgumentNullException(nameof(item)); } var fullPath = Path.GetFullPath(path); var directory = Path.GetDirectoryName(fullPath) ?? throw new DirectoryNotFoundException("The blueprint directory could not be determined."); Directory.CreateDirectory(directory); var temporaryPath = Path.Combine(directory, $".{Path.GetFileName(fullPath)}.{Guid.NewGuid():N}.tmp"); try { byte[] serializedBlueprint; using (var stream = new MemoryStream()) { if (!MyObjectBuilderSerializerKeen.SerializeXML(stream, item)) { throw new InvalidOperationException("Space Engineers could not serialize the blueprint."); } serializedBlueprint = stream.ToArray(); } File.WriteAllBytes(temporaryPath, serializedBlueprint); if (File.Exists(fullPath)) { var backupPath = fullPath + "B5"; if (File.Exists(backupPath)) { File.Delete(backupPath); } File.Replace(temporaryPath, fullPath, backupPath, true); } else { File.Move(temporaryPath, fullPath); } } finally { if (File.Exists(temporaryPath)) { File.Delete(temporaryPath); } } } }