ModernUO/Projects/UOContent/Engines/XMLSpawner/SpawnerExporter.cs
2024-02-12 18:15:12 -08:00

283 lines
8.7 KiB
C#

using Server.Commands.Generic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using Server.Engines.Spawners;
/*
** Sno's distro spawner importer/exporter
**
** [exportspawner filename - Saves distro spawners to XML to 'Saves/Spawners/filename'
**
** [importspawner filename - Restores distro spawners from 'Saves/Spawners/filename'. Note, this command does not check for
** duplication, so if you run it more than once you will end up with multiple spawners.
**
** These spawns can also be imported back in as XmlSpawners by using the '[xmlimportspawners Saves/Spawners/filename' command.
*/
namespace Server.Mobiles;
public class SpawnerExporter
{
public static void Initialize()
{
TargetCommands.Register(new ExportSpawnerCommand());
CommandSystem.Register("ImportSpawners", AccessLevel.Administrator, ImportSpawners_OnCommand);
}
public class ExportSpawnerCommand : BaseCommand
{
public ExportSpawnerCommand()
{
AccessLevel = AccessLevel.Administrator;
Supports = CommandSupport.Area | CommandSupport.Region | CommandSupport.Global | CommandSupport.Multi | CommandSupport.Single;
Commands = new[] { "ExportSpawner" };
ObjectTypes = ObjectTypes.Items;
Usage = "ExportSpawner <filename>";
Description = "Exports all Spawner objects to the specified filename.";
ListOptimized = true;
}
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
string filename = e.GetString(0);
ArrayList spawners = new ArrayList();
for (int i = 0; i < list.Count; ++i)
{
if (list[i] is Spawner)
{
Spawner spawner = (Spawner)list[i];
if (!spawner.Deleted && spawner.Map != Map.Internal && spawner.Parent == null)
{
spawners.Add(spawner);
}
}
}
AddResponse($"{spawners.Count.ToString()} spawners exported to Saves/Spawners/{filename}.");
ExportSpawners(spawners, filename);
}
public override bool ValidateArgs(BaseCommandImplementor impl, CommandEventArgs e)
{
if (e.Arguments.Length >= 1)
{
return true;
}
e.Mobile.SendMessage($"Usage: {Usage}");
return false;
}
private void ExportSpawners(ArrayList spawners, string filename)
{
if (spawners.Count == 0)
{
return;
}
if (!Directory.Exists("Saves/Spawners"))
{
Directory.CreateDirectory("Saves/Spawners");
}
string filePath = Path.Combine("Saves/Spawners", filename);
using (StreamWriter op = new StreamWriter(filePath))
{
XmlTextWriter xml = new XmlTextWriter(op)
{
Formatting = Formatting.Indented,
IndentChar = '\t',
Indentation = 1
};
xml.WriteStartDocument(true);
xml.WriteStartElement("spawners");
xml.WriteAttributeString("count", spawners.Count.ToString());
foreach (Spawner spawner in spawners)
{
ExportSpawner(spawner, xml);
}
xml.WriteEndElement();
xml.Close();
}
}
private void ExportSpawner(Spawner spawner, XmlWriter xml)
{
xml.WriteStartElement("spawner");
xml.WriteStartElement("count");
xml.WriteString(spawner.Count.ToString());
xml.WriteEndElement();
xml.WriteStartElement("group");
xml.WriteString(spawner.Group.ToString());
xml.WriteEndElement();
xml.WriteStartElement("homerange");
xml.WriteString(spawner.HomeRange.ToString());
xml.WriteEndElement();
xml.WriteStartElement("walkingrange");
xml.WriteString(spawner.WalkingRange.ToString());
xml.WriteEndElement();
xml.WriteStartElement("maxdelay");
xml.WriteString(spawner.MaxDelay.ToString());
xml.WriteEndElement();
xml.WriteStartElement("mindelay");
xml.WriteString(spawner.MinDelay.ToString());
xml.WriteEndElement();
xml.WriteStartElement("team");
xml.WriteString(spawner.Team.ToString());
xml.WriteEndElement();
xml.WriteStartElement("creaturesname");
foreach (var entry in spawner.Entries)
{
xml.WriteStartElement("creaturename");
xml.WriteString(entry.SpawnedName);
xml.WriteEndElement();
}
xml.WriteEndElement();
// Item properties
xml.WriteStartElement("name");
xml.WriteString(spawner.Name);
xml.WriteEndElement();
xml.WriteStartElement("location");
xml.WriteString(spawner.Location.ToString());
xml.WriteEndElement();
xml.WriteStartElement("map");
xml.WriteString(spawner.Map.ToString());
xml.WriteEndElement();
xml.WriteEndElement();
}
}
[Usage("ImportSpawners")]
[Description("Recreates Spawner items from the specified file.")]
public static void ImportSpawners_OnCommand(CommandEventArgs e)
{
if (e.Arguments.Length >= 1)
{
string filename = e.GetString(0);
string filePath = Path.Combine("Saves/Spawners", filename);
if (File.Exists(filePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlElement root = doc["spawners"];
int successes = 0, failures = 0;
foreach (XmlElement spawner in root.GetElementsByTagName("spawner"))
{
try
{
ImportSpawner(spawner);
successes++;
}
catch (Exception ex)
{
failures++;
Diagnostics.ExceptionLogging.LogException(ex);
}
}
e.Mobile.SendMessage($"{successes} spawners loaded successfully from {filePath}, {failures} failures.");
}
else
{
e.Mobile.SendMessage($"File {filePath} does not exist.");
}
}
else
{
e.Mobile.SendMessage("Usage: [ImportSpawners <filename>");
}
}
private static string GetText(XmlNode node, string defaultValue)
{
if (node == null)
{
return defaultValue;
}
return node.InnerText;
}
private static void ImportSpawner(XmlNode node)
{
int count = int.Parse(GetText(node["count"], "1"));
int homeRange = int.Parse(GetText(node["homerange"], "4"));
int walkingRange = int.Parse(GetText(node["walkingrange"], "-1"));
int team = int.Parse(GetText(node["team"], "0"));
bool group = bool.Parse(GetText(node["group"], "False"));
TimeSpan maxDelay = TimeSpan.Parse(GetText(node["maxdelay"], "10:00"));
TimeSpan minDelay = TimeSpan.Parse(GetText(node["mindelay"], "05:00"));
IEnumerable<string> creaturesName = LoadCreaturesName(node["creaturesname"]);
string name = GetText(node["name"], "Spawner");
Point3D location = Point3D.Parse(GetText(node["location"], "Error"));
Map map = Map.Parse(GetText(node["map"], "Error"));
Spawner spawner = new Spawner(count, minDelay, maxDelay, team, homeRange, creaturesName.ToArray());
if (walkingRange >= 0)
{
spawner.WalkingRange = walkingRange;
}
spawner.Name = name;
spawner.MoveToWorld(location, map);
if (spawner.Map == Map.Internal)
{
spawner.Delete();
throw new Exception("Spawner created on Internal map.");
}
spawner.Respawn();
}
private static IEnumerable<string> LoadCreaturesName(XmlElement node)
{
List<string> names = new List<string>();
if (node != null)
{
foreach (XmlElement ele in node.GetElementsByTagName("creaturename"))
{
if (ele != null)
{
names.Add(ele.InnerText);
}
}
}
return names;
}
}