From c867f3aa29d27675bf419d70962caa233649142a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:27:54 -0700 Subject: [PATCH] refactor(json): delete DynamicJson; spawners use SpawnerDto exclusively Remove (DynamicJson, options) constructors and ToJson(DynamicJson, ...) methods from BaseSpawner, Spawner, RegionSpawner, and ProximitySpawner. Delete DynamicJson.cs entirely. Remove now-unused using Server.Json and using System.Text.Json directives from all four files. Co-Authored-By: Claude Sonnet 4.6 --- Projects/Server/Json/DynamicJson.cs | 71 ----------- .../UOContent/Engines/Spawners/BaseSpawner.cs | 116 ------------------ .../Engines/Spawners/ProximitySpawner.cs | 21 ---- .../Engines/Spawners/RegionSpawner.cs | 17 --- .../UOContent/Engines/Spawners/Spawner.cs | 21 ---- 5 files changed, 246 deletions(-) delete mode 100644 Projects/Server/Json/DynamicJson.cs diff --git a/Projects/Server/Json/DynamicJson.cs b/Projects/Server/Json/DynamicJson.cs deleted file mode 100644 index 3b94b0a26..000000000 --- a/Projects/Server/Json/DynamicJson.cs +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2026 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: DynamicJson.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Server.Json; - -public class DynamicJson -{ - public static DynamicJson Create(Type type) => new() - { - Type = type.Name, - Data = new Dictionary() - }; - - [JsonPropertyName("type")] - public string Type { get; set; } - - [JsonExtensionData] - public Dictionary Data { get; set; } - - // TODO: Use JSON Node in .NET 6 - public void SetProperty(string key, JsonSerializerOptions options, T value) - { - using var doc = JsonDocument.Parse(JsonSerializer.SerializeToUtf8Bytes(value, options)); - Data[key] = doc.RootElement.Clone(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool GetProperty(string key, JsonSerializerOptions options, out T t) => - GetProperty(key, options, default, out t); - - public bool GetProperty(string key, JsonSerializerOptions options, T defaultT, out T t) - { - if (Data.TryGetValue(key, out var el)) - { - t = el.ToObject(options); - return true; - } - - t = defaultT; - return false; - } - - public bool GetEnumProperty(string key, JsonSerializerOptions options, out T t) where T : struct, Enum - { - if (Data.TryGetValue(key, out var el)) - { - return Enum.TryParse(el.ToObject(options), out t); - } - - t = default; - return false; - } -} diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index 81f63175e..7ceeb00f6 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -1,12 +1,10 @@ using System; using System.Collections.Generic; using System.Reflection; -using System.Text.Json; using ModernUO.Serialization; using Server.Commands; using Server.Gumps; using Server.Items; -using Server.Json; using Server.Logging; using Server.Mobiles; using static Server.Attributes; @@ -297,67 +295,6 @@ public abstract partial class BaseSpawner : Item, ISpawner } } - public BaseSpawner(DynamicJson json, JsonSerializerOptions options) : base(0x1f13) - { - if (!json.GetProperty("guid", options, out _guid)) - { - _guid = Guid.NewGuid(); - } - - if (json.GetProperty("name", options, out string name)) - { - Name = name; - } - - json.GetProperty("count", options, out int amount); - json.GetProperty("minDelay", options, DefaultMinDelay, out TimeSpan minDelay); - json.GetProperty("maxDelay", options, DefaultMaxDelay, out TimeSpan maxDelay); - json.GetProperty("team", options, out int team); - json.GetProperty("homeRange", options, -1, out int homeRange); - json.GetProperty("walkingRange", options, out _walkingRange); - - // Handle legacy homeRange format (new spawnBounds format handled by derived classes) - if (homeRange >= 0 && json.GetProperty("location", options, out Point3D location)) - { - int z; - int depth; - if (homeRange == 0) - { - z = location.Z; - depth = 0; - } - else - { - z = -128; - depth = 256; - } - - // Fall back to homeRange with location for oldest format - // Note: Map not available during JSON loading, so use location.Z directly - SpawnBounds = new Rectangle3D( - location.X - homeRange, - location.Y - homeRange, - z, - homeRange * 2 + 1, - homeRange * 2 + 1, - depth - ); - } - - json.GetProperty("spawnLocationIsHome", options, out _spawnLocationIsHome); - json.GetProperty("spawnPositionMode", options, out _spawnPositionMode); - json.GetProperty("maxSpawnAttempts", options, DefaultMaxSpawnAttempts, out _maxSpawnAttempts); - - InitSpawn(amount, minDelay, maxDelay, team, SpawnBounds); - - json.GetProperty("entries", options, out List entries); - - foreach (var entry in entries) - { - AddEntry(entry.SpawnedName, entry.SpawnedProbability, entry.SpawnedMaxCount, false, entry.Properties, entry.Parameters); - } - } - public override string DefaultName => "Spawner"; public bool IsFull => Spawned?.Count >= _count; public bool IsEmpty => Spawned?.Count == 0; @@ -496,59 +433,6 @@ public abstract partial class BaseSpawner : Item, ISpawner RemoveSpawns(); } - public virtual void ToJson(DynamicJson json, JsonSerializerOptions options) - { - json.Type = GetType().Name; - - // Always required - json.SetProperty("guid", options, _guid); - json.SetProperty("location", options, Location); - json.SetProperty("map", options, Map); - json.SetProperty("count", options, Count); - json.SetProperty("entries", options, Entries); - - // Only write if non-default - if (!string.IsNullOrEmpty(Name)) - { - json.SetProperty("name", options, Name); - } - - if (_minDelay != DefaultMinDelay) - { - json.SetProperty("minDelay", options, MinDelay); - } - - if (_maxDelay != DefaultMaxDelay) - { - json.SetProperty("maxDelay", options, MaxDelay); - } - - if (_team != 0) - { - json.SetProperty("team", options, Team); - } - - if (_walkingRange != 0) - { - json.SetProperty("walkingRange", options, WalkingRange); - } - - if (_spawnLocationIsHome) - { - json.SetProperty("spawnLocationIsHome", options, SpawnLocationIsHome); - } - - if (_spawnPositionMode is not SpawnPositionMode.Automatic and not SpawnPositionMode.Abandoned) - { - json.SetProperty("spawnPositionMode", options, _spawnPositionMode); - } - - if (_maxSpawnAttempts != DefaultMaxSpawnAttempts) - { - json.SetProperty("maxSpawnAttempts", options, _maxSpawnAttempts); - } - } - public virtual Point3D GetSpawnPosition(ISpawnable spawned, Map map) { // Abandoned spawners skip all work diff --git a/Projects/UOContent/Engines/Spawners/ProximitySpawner.cs b/Projects/UOContent/Engines/Spawners/ProximitySpawner.cs index 90dae2d43..05395d7d1 100644 --- a/Projects/UOContent/Engines/Spawners/ProximitySpawner.cs +++ b/Projects/UOContent/Engines/Spawners/ProximitySpawner.cs @@ -14,9 +14,7 @@ *************************************************************************/ using System; -using System.Text.Json; using ModernUO.Serialization; -using Server.Json; using Server.Mobiles; namespace Server.Engines.Spawners; @@ -64,29 +62,10 @@ public partial class ProximitySpawner : Spawner InstantFlag = instantFlag; } - public ProximitySpawner(DynamicJson json, JsonSerializerOptions options) : base(json, options) - { - json.GetProperty("triggerRange", options, out int triggerRange); - json.GetProperty("spawnMessage", options, out TextDefinition spawnMessage); - json.GetProperty("instant", options, out bool instant); - - TriggerRange = triggerRange; - SpawnMessage = spawnMessage; - InstantFlag = instant; - } - public override string DefaultName => "Proximity Spawner"; public override bool HandlesOnMovement => Running; - public override void ToJson(DynamicJson json, JsonSerializerOptions options) - { - base.ToJson(json, options); - json.SetProperty("triggerRange", options, TriggerRange); - json.SetProperty("spawnMessage", options, SpawnMessage); - json.SetProperty("instant", options, InstantFlag); - } - public override void DoTimer(TimeSpan delay) { if (!Running) diff --git a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs index c88d774c5..37b3d098e 100644 --- a/Projects/UOContent/Engines/Spawners/RegionSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/RegionSpawner.cs @@ -14,9 +14,7 @@ *************************************************************************/ using System; -using System.Text.Json; using ModernUO.Serialization; -using Server.Json; using Server.Regions; namespace Server.Engines.Spawners; @@ -52,15 +50,6 @@ public partial class RegionSpawner : Spawner { } - public RegionSpawner(DynamicJson json, JsonSerializerOptions options) : base(json, options) - { - json.GetProperty("map", options, out Map map); - json.GetProperty("region", options, out string spawnRegion); - - _spawnRegion = Region.Find(spawnRegion, map) as BaseRegion; - _spawnRegion?.InitRectangles(); - } - [CommandProperty(AccessLevel.Developer)] public BaseRegion SpawnRegion { @@ -116,12 +105,6 @@ public partial class RegionSpawner : Spawner return base.GetSpawnPosition(spawned, map); } - public override void ToJson(DynamicJson json, JsonSerializerOptions options) - { - base.ToJson(json, options); - json.SetProperty("region", options, SpawnRegion.Name); - } - public override void GetSpawnerProperties(IPropertyList list) { base.GetSpawnerProperties(list); diff --git a/Projects/UOContent/Engines/Spawners/Spawner.cs b/Projects/UOContent/Engines/Spawners/Spawner.cs index 32bde4de1..7c07d2681 100644 --- a/Projects/UOContent/Engines/Spawners/Spawner.cs +++ b/Projects/UOContent/Engines/Spawners/Spawner.cs @@ -1,7 +1,5 @@ using System; -using System.Text.Json; using ModernUO.Serialization; -using Server.Json; namespace Server.Engines.Spawners; @@ -57,25 +55,6 @@ public partial class Spawner : BaseSpawner { } - public Spawner(DynamicJson json, JsonSerializerOptions options) : base(json, options) - { - // Read spawnBounds (not in BaseSpawner to allow RegionSpawner to skip it) - if (json.GetProperty("spawnBounds", options, out Rectangle3D spawnBounds)) - { - SpawnBounds = spawnBounds; - } - } - - public override void ToJson(DynamicJson json, JsonSerializerOptions options) - { - base.ToJson(json, options); - - if (SpawnBounds != default) - { - json.SetProperty("spawnBounds", options, SpawnBounds); - } - } - public override Region Region => Region.Find(Location, Map); protected override bool SupportsSpiralScan => _useSpiralScan;