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> { 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, bool skipHook, ISerializationContext? context = null, Dictionary? value = default) { var data = serializationManager.Read(node, context, skipHook); 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); } public Dictionary Copy(ISerializationManager serializationManager, Dictionary source, Dictionary target, bool skipHook, ISerializationContext? context = null) { serializationManager.Copy(source, ref target, context, skipHook); return target; } [DataDefinition] private struct TileAtmosData { [DataField("uniqueMixes")] public List? UniqueMixes; [DataField("tiles")] public Dictionary? TilesUniqueMixes; } }