diff --git a/Projects/UOContent.Tests/Tests/Commands/Objects/ObjectCacheBuilderTests.cs b/Projects/UOContent.Tests/Tests/Commands/Objects/ObjectCacheBuilderTests.cs new file mode 100644 index 000000000..860822597 --- /dev/null +++ b/Projects/UOContent.Tests/Tests/Commands/Objects/ObjectCacheBuilderTests.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using Server.Commands; +using Server.Items; +using Xunit; + +namespace UOContent.Tests.Commands.Objects; + +public class ObjectCacheBuilderTests +{ + [Fact] + public void Build_produces_index_row_and_detail_chunk() + { + var extracted = new ExtractedObject( + typeof(Runebook), + "item", + "Items.Skill Items.Magical", + new LeanMetadata(8901, 0x461, "runebook", 1041267), + [new CtorDoc()], + [new PropertyDoc { Name = "Hue", Type = "int" }], + [new OplLine { Cliloc = 1041267 }], + "Item" + ); + + var (index, chunks) = ObjectCacheBuilder.Build([extracted], "2026-07-19T00:00:00Z"); + + var row = Assert.Single(index.Objects); + Assert.Equal("Runebook", row.Type); + Assert.Equal("items.skill-items.magical", row.Chunk); + Assert.Equal(8901, row.ItemID); + + var chunk = Assert.Contains("items.skill-items.magical", chunks); + Assert.Contains("Runebook", chunk.Keys); + Assert.Equal("Item", chunk["Runebook"].BaseType); + } +} diff --git a/Projects/UOContent/Commands/Object Creation/ObjectCacheBuilder.cs b/Projects/UOContent/Commands/Object Creation/ObjectCacheBuilder.cs new file mode 100644 index 000000000..0ce79145f --- /dev/null +++ b/Projects/UOContent/Commands/Object Creation/ObjectCacheBuilder.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +namespace Server.Commands; + +public sealed record ExtractedObject( + Type Type, + string Entity, + string Category, + LeanMetadata Lean, + List Ctors, + List Properties, + List Opl, + string BaseType +); + +public static class ObjectCacheBuilder +{ + public static (ObjectIndexFile index, Dictionary> chunks) Build( + IReadOnlyList objects, string generatedUtc + ) + { + var index = new ObjectIndexFile { GeneratedUtc = generatedUtc }; + var chunks = new Dictionary>(); + + foreach (var obj in objects) + { + var chunkKey = ObjectNaming.ChunkKey(obj.Category); + + index.Objects.Add( + new ObjectIndexEntry + { + Type = obj.Type.Name, + Entity = obj.Entity, + Category = obj.Category, + Chunk = chunkKey, + ItemID = obj.Lean.ItemID, + Hue = obj.Lean.Hue, + Name = obj.Lean.Name, + Cliloc = obj.Lean.Cliloc + } + ); + + if (!chunks.TryGetValue(chunkKey, out var chunk)) + { + chunks[chunkKey] = chunk = new Dictionary(); + } + + chunk[obj.Type.Name] = new ObjectDetail + { + BaseType = obj.BaseType, + Ctors = obj.Ctors, + Properties = obj.Properties, + Opl = obj.Opl + }; + } + + return (index, chunks); + } +}