using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager; using Robust.Shared.Serialization.Markdown; using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Serialization.Markdown.Validation; using Robust.Shared.Serialization.TypeSerializers.Interfaces; namespace Content.Server.Atmos.Serialization; public sealed class TileAtmosCollectionSerializer : ITypeSerializer, MappingDataNode>, ITypeCopier> { public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies, ISerializationContext? context = null) { return serializationManager.ValidateNode(node, context); } public Dictionary Read(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate>? instanceProvider = null) { var data = serializationManager.Read(node, hookCtx, context); var tiles = new Dictionary(); if (data.TilesUniqueMixes != null) { foreach (var (indices, mix) in data.TilesUniqueMixes) { try { tiles.Add(indices, new TileAtmosphere(EntityUid.Invalid, indices, data.UniqueMixes![mix].Clone())); } catch (ArgumentOutOfRangeException) { Logger.Error( $"Error during atmos serialization! Tile at {indices} points to an unique mix ({mix}) out of range!"); } } } return tiles; } public DataNode Write(ISerializationManager serializationManager, Dictionary value, IDependencyCollection dependencies, bool alwaysWrite = false, ISerializationContext? context = null) { var uniqueMixes = new List(); var uniqueMixHash = new Dictionary(); var tiles = new Dictionary(); foreach (var (indices, tile) in value) { if (tile.Air == null) continue; if (uniqueMixHash.TryGetValue(tile.Air, out var index)) { tiles[indices] = index; continue; } uniqueMixes.Add(tile.Air); var newIndex = uniqueMixes.Count - 1; uniqueMixHash[tile.Air] = newIndex; tiles[indices] = newIndex; } if (uniqueMixes.Count == 0) uniqueMixes = null; if (tiles.Count == 0) tiles = null; return serializationManager.WriteValue(new TileAtmosData { UniqueMixes = uniqueMixes, TilesUniqueMixes = tiles }, alwaysWrite, context); } [DataDefinition] private struct TileAtmosData { [DataField("uniqueMixes")] public List? UniqueMixes; [DataField("tiles")] public Dictionary? TilesUniqueMixes; } public void CopyTo(ISerializationManager serializationManager, Dictionary source, ref Dictionary target, SerializationHookContext hookCtx, ISerializationContext? context = null) { target.Clear(); foreach (var (key, val) in source) { target.Add(key, new TileAtmosphere( val.GridIndex, val.GridIndices, val.Air?.Clone(), val.Air?.Immutable ?? false, val.Space)); } } }