using System.IO; using Content.Server.Administration.Managers; using Content.Shared.Administration; using Content.Shared.Mapping; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.EntitySerialization; using Robust.Shared.EntitySerialization.Systems; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Serialization; using Robust.Shared.Utility; using YamlDotNet.Core; using YamlDotNet.RepresentationModel; namespace Content.Server.Mapping; public sealed class MappingManager : IPostInjectInit { [Dependency] private readonly IAdminManager _admin = default!; [Dependency] private readonly ILogManager _log = default!; [Dependency] private readonly IMapManager _map = default!; [Dependency] private readonly IServerNetManager _net = default!; [Dependency] private readonly IPlayerManager _players = default!; [Dependency] private readonly IEntitySystemManager _systems = default!; [Dependency] private readonly IEntityManager _ent = default!; private ISawmill _sawmill = default!; private ZStdCompressionContext _zstd = default!; public void PostInject() { #if !FULL_RELEASE _net.RegisterNetMessage(OnMappingSaveMap); _net.RegisterNetMessage(); _net.RegisterNetMessage(); _sawmill = _log.GetSawmill("mapping"); _zstd = new ZStdCompressionContext(); #endif } private void OnMappingSaveMap(MappingSaveMapMessage message) { #if !FULL_RELEASE try { if (!_players.TryGetSessionByChannel(message.MsgChannel, out var session) || !_admin.IsAdmin(session, true) || !_admin.HasAdminFlag(session, AdminFlags.Host) || !_ent.TryGetComponent(session.AttachedEntity, out TransformComponent? xform) || xform.MapUid is not {} mapUid) { return; } var data = _systems.GetEntitySystem().SerializeEntityRecursive(mapUid).Node; var document = new YamlDocument(data.ToYaml()); var stream = new YamlStream { document }; var writer = new StringWriter(); stream.Save(new YamlMappingFix(new Emitter(writer)), false); var msg = new MappingMapDataMessage() { Context = _zstd, Yml = writer.ToString() }; _net.ServerSendMessage(msg, message.MsgChannel); } catch (Exception e) { _sawmill.Error($"Error saving map in mapping mode:\n{e}"); var msg = new MappingSaveMapErrorMessage(); _net.ServerSendMessage(msg, message.MsgChannel); } #endif } }