CatStation/Content.Server/Corvax/GuideGenerator/ComponentJsonGenerator.cs
2026-05-12 18:38:50 +07:00

110 lines
3.9 KiB
C#

using System.Text.Encodings.Web;
using System.Text.Json;
using Robust.Shared.ContentPack;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Utility;
namespace Content.Server.Corvax.GuideGenerator;
public static class ComponentJsonGenerator
{
private static readonly JsonSerializerOptions SerializeOptions = new()
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public static void PublishAll(IResourceManager res, ResPath destRoot)
{
var proto = IoCManager.Resolve<IPrototypeManager>();
var ser = IoCManager.Resolve<ISerializationManager>();
var compFactory = IoCManager.Resolve<IComponentFactory>();
var entMan = IoCManager.Resolve<IEntityManager>();
// Map: component name -> (entity id -> component fields)
var output = new Dictionary<string, Dictionary<string, object?>>();
foreach (var p in proto.EnumeratePrototypes(typeof(EntityPrototype)))
{
if (p is not EntityPrototype entProto)
continue;
var composedComponents = YAMLEntry.GetComposedComponentMappings(entProto, proto, ser, compFactory);
foreach (var (compName, entry) in entProto.Components)
{
var node = ser.WriteValueAs<MappingDataNode>(entry.Component.GetType(), entry.Component);
FieldEntry.NormalizeFlagsToSequences(entry.Component, node);
var compFields = FieldEntry.DataNodeToObject(node);
if (!output.TryGetValue(compName, out var map))
{
map = new Dictionary<string, object?>();
output[compName] = map;
}
map[entProto.ID] = compFields;
}
foreach (var (compName, node) in composedComponents)
{
if (entProto.Components.ContainsKey(compName))
continue;
var compFields = FieldEntry.DataNodeToObject(node);
if (!output.TryGetValue(compName, out var map))
{
map = new Dictionary<string, object?>();
output[compName] = map;
}
map[entProto.ID] = compFields;
}
}
if (output.Count == 0)
return;
foreach (var (compName, map) in output)
{
// Determine default field for this component.
object? defaultObj = null;
if (compFactory.TryGetRegistration(compName, out var registration))
{
var uid = entMan.CreateEntityUninitialized(null);
try
{
var compInstance = compFactory.GetComponent(registration.Type);
FieldEntry.EnsureFieldsCollectionsInitialized(compInstance);
entMan.AddComponent(uid, compInstance);
var node = ser.WriteValueAs<MappingDataNode>(compInstance.GetType(), compInstance, true);
FieldEntry.NormalizeFlagsToSequences(compInstance, node);
defaultObj = FieldEntry.DataNodeToObject(node);
}
catch
{
defaultObj = new Dictionary<string, object?>();
}
finally
{
entMan.DeleteEntity(uid);
}
}
var outObj = new Dictionary<string, object?>
{
["default"] = defaultObj,
["id"] = map
};
res.UserData.CreateDir(destRoot);
var fileName = TextTools.DecapitalizeString(compName) + ".json";
using var stream = res.UserData.OpenWrite(destRoot / fileName);
JsonSerializer.Serialize(stream, outObj, SerializeOptions);
}
}
}