ModernUO/Projects/UOContent/Commands/Object Creation/CategorizationSync.cs
Kamron Batman 8f20106aec
feat(objects): CategorizationSync.Reconcile — append Uncategorized + report orphans
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 12:38:03 -07:00

77 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Server.Items;
namespace Server.Commands;
public sealed record SyncReport(List<string> Appended, List<string> Orphaned);
public static class CategorizationSync
{
public static (List<CAGJson> updated, SyncReport report) Reconcile(
List<CAGJson> categorization, IReadOnlyList<Type> discovered
)
{
var categorizedTypes = new HashSet<Type>();
foreach (var cag in categorization)
{
foreach (var obj in cag.Objects ?? [])
{
if (obj.Type != null)
{
categorizedTypes.Add(obj.Type);
}
}
}
var discoveredSet = new HashSet<Type>(discovered);
var orphaned = categorizedTypes
.Where(t => !discoveredSet.Contains(t))
.Select(t => t.Name)
.OrderBy(n => n, StringComparer.Ordinal)
.ToList();
var updated = new List<CAGJson>(categorization);
var appended = new List<string>();
var itemAppend = new List<CAGObject>();
var mobileAppend = new List<CAGObject>();
foreach (var type in discovered)
{
if (categorizedTypes.Contains(type))
{
continue;
}
appended.Add(type.Name);
var target = typeof(Mobile).IsAssignableFrom(type) ? mobileAppend : itemAppend;
target.Add(new CAGObject { Type = type });
}
AppendUncategorized(updated, "Items.Uncategorized", itemAppend);
AppendUncategorized(updated, "Mobiles.Uncategorized", mobileAppend);
return (updated, new SyncReport(appended, orphaned));
}
private static void AppendUncategorized(List<CAGJson> updated, string category, List<CAGObject> toAdd)
{
if (toAdd.Count == 0)
{
return;
}
var existing = updated.FirstOrDefault(c => c.Category == category);
if (existing == null)
{
updated.Add(new CAGJson { Category = category, Objects = toAdd.ToArray() });
return;
}
var merged = new List<CAGObject>(existing.Objects ?? []);
merged.AddRange(toAdd);
updated[updated.IndexOf(existing)] = existing with { Objects = merged.ToArray() };
}
}