refactor(spawners): export via typed SpawnerJsonSerializer

Rewire ExportSpawnersCommand.ExecuteList to build List<BaseSpawner>
and serialize via SpawnerJsonSerializer.Options instead of the
DynamicJson.Create + spawner.ToJson loop. Add file serialize→deserialize
round-trip test with exception-safe cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-06-25 10:55:21 -07:00
parent 206d938395
commit ad640f80da
2 changed files with 43 additions and 7 deletions

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server;
using Server.Engines.Spawners;
using Server.Json;
using Xunit;
namespace UOContent.Tests.Engines.Spawners.Json;
[Collection("Sequential UOContent Tests")]
public class ExportImportFileTests
{
[Fact]
public void Serialize_ThenDeserialize_File_PreservesSpawner()
{
var spawner = new Spawner(3, TimeSpan.FromMinutes(4), TimeSpan.FromMinutes(8), 1,
new Rectangle3D(200, 200, 0, 9, 9, 0), "Tanner");
spawner.MoveToWorld(new Point3D(204, 204, 0), Map.Felucca);
var path = Path.GetTempFileName();
try
{
JsonConfig.Serialize(path, new List<BaseSpawner> { spawner }, SpawnerJsonSerializer.Options);
var loaded = JsonConfig.Deserialize<List<BaseSpawner>>(path, SpawnerJsonSerializer.Options);
var s = Assert.IsType<Spawner>(Assert.Single(loaded));
Assert.Equal(3, s.Count);
Assert.Equal(1, s.Team);
Assert.Equal(new Rectangle3D(200, 200, 0, 9, 9, 0), s.SpawnBounds);
s.Delete();
}
finally
{
File.Delete(path);
spawner?.Delete();
}
}
}

View file

@ -66,9 +66,7 @@ public class ExportSpawnersCommand : BaseCommand
NetState.FlushAll();
var options = JsonConfig.GetOptions(new TextDefinitionConverterFactory());
var spawnRecords = new List<DynamicJson>(list.Count);
var spawnRecords = new List<BaseSpawner>(list.Count);
for (var i = 0; i < list.Count; i++)
{
// Not a spawner, not on a valid map, or is in a container
@ -85,9 +83,7 @@ public class ExportSpawnersCommand : BaseCommand
continue;
}
var dynamicJson = DynamicJson.Create(spawner.GetType());
spawner.ToJson(dynamicJson, options);
spawnRecords.Add(dynamicJson);
spawnRecords.Add(spawner);
}
if (spawnRecords.Count == 0)
@ -98,7 +94,7 @@ public class ExportSpawnersCommand : BaseCommand
e.Mobile.SendMessage("Exporting spawners...");
JsonConfig.Serialize(path, spawnRecords, options);
JsonConfig.Serialize(path, spawnRecords, SpawnerJsonSerializer.Options);
e.Mobile.SendMessage($"Spawners exported to {path}");
}