Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,44 @@
using System;
using Server;
using Server.Mobiles;
using Server.Commands;
using System.Linq;
using System.Collections.Generic;
using Server.SkillHandlers;
using Server.Accounting;
using System.IO;
namespace Server.Items
{
public static class AccountGoldCheck
{
public static void Initialize()
{
CommandSystem.Register("CheckAccountGold", AccessLevel.Administrator, e =>
{
double currency = 0.0;
var table = new Dictionary<string, long>();
foreach (var account in Accounts.GetAccounts().OfType<Account>())
{
table[account.Username] = (long)(account.TotalCurrency * Account.CurrencyThreshold);
currency += account.TotalCurrency;
}
using (StreamWriter op = new StreamWriter("TotalAccountGold.txt", true))
{
foreach (var kvp in table.OrderBy(k => -k.Value))
{
op.WriteLine(
String.Format("{0} currency: {1}", kvp.Key, kvp.Value.ToString("N0", System.Globalization.CultureInfo.GetCultureInfo("en-US"))));
}
op.WriteLine("");
op.WriteLine("Total Accounts: {0}", table.Count);
op.WriteLine("Total Shard Gold: {0}", (currency * Account.CurrencyThreshold).ToString("N0", System.Globalization.CultureInfo.GetCultureInfo("en-US")));
}
});
}
}
}

724
Scripts/Commands/Add.cs Normal file
View File

@@ -0,0 +1,724 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Server.Items;
using Server.Targeting;
using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands
{
public class Add
{
private static readonly Type m_EntityType = typeof(IEntity);
private static readonly Type m_ConstructableType = typeof(ConstructableAttribute);
private static readonly Type m_EnumType = typeof(Enum);
private static readonly Type m_TypeType = typeof(Type);
private static readonly Type m_ParsableType = typeof(ParsableAttribute);
private static readonly Type[] m_ParseTypes = new Type[] { typeof(string) };
private static readonly object[] m_ParseArgs = new object[1];
private static readonly Type[] m_SignedNumerics = new Type[]
{
typeof(Int64),
typeof(Int32),
typeof(Int16),
typeof(SByte)
};
private static readonly Type[] m_UnsignedNumerics = new Type[]
{
typeof(UInt64),
typeof(UInt32),
typeof(UInt16),
typeof(Byte)
};
private enum TileZType
{
Start,
Fixed,
MapAverage
}
public static void Initialize()
{
CommandSystem.Register("Tile", AccessLevel.GameMaster, new CommandEventHandler(Tile_OnCommand));
CommandSystem.Register("TileRXYZ", AccessLevel.GameMaster, new CommandEventHandler(TileRXYZ_OnCommand));
CommandSystem.Register("TileXYZ", AccessLevel.GameMaster, new CommandEventHandler(TileXYZ_OnCommand));
CommandSystem.Register("TileZ", AccessLevel.GameMaster, new CommandEventHandler(TileZ_OnCommand));
CommandSystem.Register("TileAvg", AccessLevel.GameMaster, new CommandEventHandler(TileAvg_OnCommand));
CommandSystem.Register("Outline", AccessLevel.GameMaster, new CommandEventHandler(Outline_OnCommand));
CommandSystem.Register("OutlineRXYZ", AccessLevel.GameMaster, new CommandEventHandler(OutlineRXYZ_OnCommand));
CommandSystem.Register("OutlineXYZ", AccessLevel.GameMaster, new CommandEventHandler(OutlineXYZ_OnCommand));
CommandSystem.Register("OutlineZ", AccessLevel.GameMaster, new CommandEventHandler(OutlineZ_OnCommand));
CommandSystem.Register("OutlineAvg", AccessLevel.GameMaster, new CommandEventHandler(OutlineAvg_OnCommand));
}
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args)
{
Invoke(from, start, end, args, null, false, false);
}
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs)
{
Invoke(from, start, end, args, packs, false, false);
}
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs, bool outline, bool mapAvg)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0} {1} building ", from.AccessLevel, CommandLogging.Format(from));
if (start == end)
sb.AppendFormat("at {0} in {1}", start, from.Map);
else
sb.AppendFormat("from {0} to {1} in {2}", start, end, from.Map);
sb.Append(":");
for (int i = 0; i < args.Length; ++i)
sb.AppendFormat(" \"{0}\"", args[i]);
CommandLogging.WriteLine(from, sb.ToString());
string name = args[0];
FixArgs(ref args);
string[,] props = null;
for (int i = 0; i < args.Length; ++i)
{
if (Insensitive.Equals(args[i], "set"))
{
int remains = args.Length - i - 1;
if (remains >= 2)
{
props = new string[remains / 2, 2];
remains /= 2;
for (int j = 0; j < remains; ++j)
{
props[j, 0] = args[i + (j * 2) + 1];
props[j, 1] = args[i + (j * 2) + 2];
}
FixSetString(ref args, i);
}
break;
}
}
Type type = ScriptCompiler.FindTypeByName(name);
if (!IsEntity(type))
{
from.SendMessage("No type with that name was found.");
return;
}
DateTime time = DateTime.UtcNow;
int built = BuildObjects(from, type, start, end, args, props, packs, outline, mapAvg);
if (built > 0)
from.SendMessage("{0} object{1} generated in {2:F1} seconds.", built, built != 1 ? "s" : "", (DateTime.UtcNow - time).TotalSeconds);
else
SendUsage(type, from);
}
public static void FixSetString(ref string[] args, int index)
{
string[] old = args;
args = new string[index];
Array.Copy(old, 0, args, 0, index);
}
public static void FixArgs(ref string[] args)
{
string[] old = args;
args = new string[args.Length - 1];
Array.Copy(old, 1, args, 0, args.Length);
}
public static int BuildObjects(Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props, List<Container> packs)
{
return BuildObjects(from, type, start, end, args, props, packs, false, false);
}
public static int BuildObjects(Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props, List<Container> packs, bool outline, bool mapAvg)
{
Utility.FixPoints(ref start, ref end);
PropertyInfo[] realProps = null;
if (props != null)
{
realProps = new PropertyInfo[props.GetLength(0)];
PropertyInfo[] allProps = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
for (int i = 0; i < realProps.Length; ++i)
{
PropertyInfo thisProp = null;
string propName = props[i, 0];
for (int j = 0; thisProp == null && j < allProps.Length; ++j)
{
if (Insensitive.Equals(propName, allProps[j].Name))
thisProp = allProps[j];
}
if (thisProp == null)
{
from.SendMessage("Property not found: {0}", propName);
}
else
{
CPA attr = Properties.GetCPA(thisProp);
if (attr == null)
from.SendMessage("Property ({0}) not found.", propName);
else if (from.AccessLevel < attr.WriteLevel)
from.SendMessage("Setting this property ({0}) requires at least {1} access level.", propName, Mobile.GetAccessLevelName(attr.WriteLevel));
else if (!thisProp.CanWrite || attr.ReadOnly)
from.SendMessage("Property ({0}) is read only.", propName);
else
realProps[i] = thisProp;
}
}
}
ConstructorInfo[] ctors = type.GetConstructors();
for (int i = 0; i < ctors.Length; ++i)
{
ConstructorInfo ctor = ctors[i];
if (!IsConstructable(ctor, from.AccessLevel))
continue;
ParameterInfo[] paramList = ctor.GetParameters();
if (args.Length == paramList.Length)
{
object[] paramValues = ParseValues(paramList, args);
if (paramValues == null)
continue;
int built = Build(from, start, end, ctor, paramValues, props, realProps, packs, outline, mapAvg);
if (built > 0)
return built;
}
}
return 0;
}
public static object[] ParseValues(ParameterInfo[] paramList, string[] args)
{
object[] values = new object[args.Length];
for (int i = 0; i < args.Length; ++i)
{
object value = ParseValue(paramList[i].ParameterType, args[i]);
if (value != null)
values[i] = value;
else
return null;
}
return values;
}
public static object ParseValue(Type type, string value)
{
try
{
if (IsEnum(type))
{
return Enum.Parse(type, value, true);
}
else if (IsType(type))
{
return ScriptCompiler.FindTypeByName(value);
}
else if (IsParsable(type))
{
return ParseParsable(type, value);
}
else
{
object obj = value;
if (value != null && value.StartsWith("0x"))
{
if (IsSignedNumeric(type))
obj = Convert.ToInt64(value.Substring(2), 16);
else if (IsUnsignedNumeric(type))
obj = Convert.ToUInt64(value.Substring(2), 16);
obj = Convert.ToInt32(value.Substring(2), 16);
}
if (obj == null && !type.IsValueType)
return null;
else
return Convert.ChangeType(obj, type);
}
}
catch
{
return null;
}
}
public static IEntity Build(Mobile from, ConstructorInfo ctor, object[] values, string[,] props, PropertyInfo[] realProps, ref bool sendError)
{
object built = ctor.Invoke(values);
if (built != null && realProps != null)
{
bool hadError = false;
for (int i = 0; i < realProps.Length; ++i)
{
if (realProps[i] == null)
continue;
string result = Properties.InternalSetValue(from, built, built, realProps[i], props[i, 1], props[i, 1], false);
if (result != "Property has been set.")
{
if (sendError)
from.SendMessage(result);
hadError = true;
}
}
if (hadError)
sendError = false;
}
return (IEntity)built;
}
public static int Build(Mobile from, Point3D start, Point3D end, ConstructorInfo ctor, object[] values, string[,] props, PropertyInfo[] realProps, List<Container> packs)
{
return Build(from, start, end, ctor, values, props, realProps, packs, false, false);
}
public static int Build(Mobile from, Point3D start, Point3D end, ConstructorInfo ctor, object[] values, string[,] props, PropertyInfo[] realProps, List<Container> packs, bool outline, bool mapAvg)
{
try
{
Map map = from.Map;
int width = end.X - start.X + 1;
int height = end.Y - start.Y + 1;
if (outline && (width < 3 || height < 3))
outline = false;
int objectCount;
if (packs != null)
objectCount = packs.Count;
else if (outline)
objectCount = (width + height - 2) * 2;
else
objectCount = width * height;
if (objectCount >= 20)
from.SendMessage("Constructing {0} objects, please wait.", objectCount);
bool sendError = true;
StringBuilder sb = new StringBuilder();
sb.Append("Serials: ");
if (packs != null)
{
for (int i = 0; i < packs.Count; ++i)
{
IEntity built = Build(from, ctor, values, props, realProps, ref sendError);
sb.AppendFormat("0x{0:X}; ", built.Serial.Value);
if (built is Item)
{
Container pack = packs[i];
pack.DropItem((Item)built);
}
else if (built is Mobile)
{
Mobile m = (Mobile)built;
m.MoveToWorld(new Point3D(start.X, start.Y, start.Z), map);
}
}
}
else
{
int z = start.Z;
for (int x = start.X; x <= end.X; ++x)
{
for (int y = start.Y; y <= end.Y; ++y)
{
if (outline && x != start.X && x != end.X && y != start.Y && y != end.Y)
continue;
if (mapAvg)
z = map.GetAverageZ(x, y);
IEntity built = Build(from, ctor, values, props, realProps, ref sendError);
sb.AppendFormat("0x{0:X}; ", built.Serial.Value);
if (built is Item)
{
Item item = (Item)built;
item.MoveToWorld(new Point3D(x, y, z), map);
}
else if (built is Mobile)
{
Mobile m = (Mobile)built;
m.MoveToWorld(new Point3D(x, y, z), map);
}
}
}
}
CommandLogging.WriteLine(from, sb.ToString());
return objectCount;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return 0;
}
}
public static void SendUsage(Type type, Mobile from)
{
ConstructorInfo[] ctors = type.GetConstructors();
bool foundCtor = false;
for (int i = 0; i < ctors.Length; ++i)
{
ConstructorInfo ctor = ctors[i];
if (!IsConstructable(ctor, from.AccessLevel))
continue;
if (!foundCtor)
{
foundCtor = true;
from.SendMessage("Usage:");
}
SendCtor(type, ctor, from);
}
if (!foundCtor)
from.SendMessage("That type is not marked constructable.");
}
public static void SendCtor(Type type, ConstructorInfo ctor, Mobile from)
{
ParameterInfo[] paramList = ctor.GetParameters();
StringBuilder sb = new StringBuilder();
sb.Append(type.Name);
for (int i = 0; i < paramList.Length; ++i)
{
if (i != 0)
sb.Append(',');
sb.Append(' ');
sb.Append(paramList[i].ParameterType.Name);
sb.Append(' ');
sb.Append(paramList[i].Name);
}
from.SendMessage(sb.ToString());
}
[Usage("Tile <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name into a targeted bounding box. Optional constructor parameters. Optional set property list.")]
public static void Tile_OnCommand(CommandEventArgs e)
{
Internal_OnCommand(e, false);
}
[Usage("TileRXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name into a given bounding box, (x, y) parameters are relative to your characters position. Optional constructor parameters. Optional set property list.")]
public static void TileRXYZ_OnCommand(CommandEventArgs e)
{
InternalRXYZ_OnCommand(e, false);
}
[Usage("TileXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name into a given bounding box. Optional constructor parameters. Optional set property list.")]
public static void TileXYZ_OnCommand(CommandEventArgs e)
{
InternalXYZ_OnCommand(e, false);
}
[Usage("TileZ <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name into a targeted bounding box at a fixed Z location. Optional constructor parameters. Optional set property list.")]
public static void TileZ_OnCommand(CommandEventArgs e)
{
InternalZ_OnCommand(e, false);
}
[Usage("TileAvg <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name into a targeted bounding box on the map's average Z elevation. Optional constructor parameters. Optional set property list.")]
public static void TileAvg_OnCommand(CommandEventArgs e)
{
InternalAvg_OnCommand(e, false);
}
[Usage("Outline <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name around a targeted bounding box. Optional constructor parameters. Optional set property list.")]
public static void Outline_OnCommand(CommandEventArgs e)
{
Internal_OnCommand(e, true);
}
[Usage("OutlineRXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name around a given bounding box, (x, y) parameters are relative to your characters position. Optional constructor parameters. Optional set property list.")]
public static void OutlineRXYZ_OnCommand(CommandEventArgs e)
{
InternalRXYZ_OnCommand(e, true);
}
[Usage("OutlineXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name around a given bounding box. Optional constructor parameters. Optional set property list.")]
public static void OutlineXYZ_OnCommand(CommandEventArgs e)
{
InternalXYZ_OnCommand(e, true);
}
[Usage("OutlineZ <z> <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name around a targeted bounding box at a fixed Z location. Optional constructor parameters. Optional set property list.")]
public static void OutlineZ_OnCommand(CommandEventArgs e)
{
InternalZ_OnCommand(e, true);
}
[Usage("OutlineAvg <name> [params] [set {<propertyName> <value> ...}]")]
[Description("Tiles an item or npc by name around a targeted bounding box on the map's average Z elevation. Optional constructor parameters. Optional set property list.")]
public static void OutlineAvg_OnCommand(CommandEventArgs e)
{
InternalAvg_OnCommand(e, true);
}
public static bool IsEntity(Type t)
{
return t != null && t.GetInterface(m_EntityType.Name) != null;
}
public static bool IsConstructable(ConstructorInfo ctor, AccessLevel accessLevel)
{
object[] attrs = ctor.GetCustomAttributes(m_ConstructableType, false);
if (attrs.Length == 0)
return false;
return accessLevel >= ((ConstructableAttribute)attrs[0]).AccessLevel;
}
public static bool IsEnum(Type type)
{
return type.IsSubclassOf(m_EnumType);
}
public static bool IsType(Type type)
{
return (type == m_TypeType || type.IsSubclassOf(m_TypeType));
}
public static bool IsParsable(Type type)
{
return type.IsDefined(m_ParsableType, false);
}
public static object ParseParsable(Type type, string value)
{
MethodInfo method = type.GetMethod("Parse", m_ParseTypes);
m_ParseArgs[0] = value;
return method.Invoke(null, m_ParseArgs);
}
public static bool IsSignedNumeric(Type type)
{
for (int i = 0; i < m_SignedNumerics.Length; ++i)
if (type == m_SignedNumerics[i])
return true;
return false;
}
public static bool IsUnsignedNumeric(Type type)
{
for (int i = 0; i < m_UnsignedNumerics.Length; ++i)
if (type == m_UnsignedNumerics[i])
return true;
return false;
}
private static void TileBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
TileState ts = (TileState)state;
bool mapAvg = false;
switch ( ts.m_ZType )
{
case TileZType.Fixed:
{
start.Z = end.Z = ts.m_FixedZ;
break;
}
case TileZType.MapAverage:
{
mapAvg = true;
break;
}
}
Invoke(from, start, end, ts.m_Args, null, ts.m_Outline, mapAvg);
}
private static void Internal_OnCommand(CommandEventArgs e, bool outline)
{
if (e.Length >= 1)
BoundingBoxPicker.Begin(e.Mobile, new BoundingBoxCallback(TileBox_Callback), new TileState(TileZType.Start, 0, e.Arguments, outline));
else
e.Mobile.SendMessage("Format: {0} <type> [params] [set {{<propertyName> <value> ...}}]", outline ? "Outline" : "Tile");
}
private static void InternalRXYZ_OnCommand(CommandEventArgs e, bool outline)
{
if (e.Length >= 6)
{
Point3D p = new Point3D(e.Mobile.X + e.GetInt32(0), e.Mobile.Y + e.GetInt32(1), e.Mobile.Z + e.GetInt32(4));
Point3D p2 = new Point3D(p.X + e.GetInt32(2) - 1, p.Y + e.GetInt32(3) - 1, p.Z);
string[] subArgs = new string[e.Length - 5];
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 5];
Add.Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
}
else
{
e.Mobile.SendMessage("Format: {0}RXYZ <x> <y> <w> <h> <z> <type> [params] [set {{<propertyName> <value> ...}}]", outline ? "Outline" : "Tile");
}
}
private static void InternalXYZ_OnCommand(CommandEventArgs e, bool outline)
{
if (e.Length >= 6)
{
Point3D p = new Point3D(e.GetInt32(0), e.GetInt32(1), e.GetInt32(4));
Point3D p2 = new Point3D(p.X + e.GetInt32(2) - 1, p.Y + e.GetInt32(3) - 1, e.GetInt32(4));
string[] subArgs = new string[e.Length - 5];
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 5];
Add.Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
}
else
{
e.Mobile.SendMessage("Format: {0}XYZ <x> <y> <w> <h> <z> <type> [params] [set {{<propertyName> <value> ...}}]", outline ? "Outline" : "Tile");
}
}
private static void InternalZ_OnCommand(CommandEventArgs e, bool outline)
{
if (e.Length >= 2)
{
string[] subArgs = new string[e.Length - 1];
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 1];
BoundingBoxPicker.Begin(e.Mobile, new BoundingBoxCallback(TileBox_Callback), new TileState(TileZType.Fixed, e.GetInt32(0), subArgs, outline));
}
else
{
e.Mobile.SendMessage("Format: {0}Z <z> <type> [params] [set {{<propertyName> <value> ...}}]", outline ? "Outline" : "Tile");
}
}
private static void InternalAvg_OnCommand(CommandEventArgs e, bool outline)
{
if (e.Length >= 1)
BoundingBoxPicker.Begin(e.Mobile, new BoundingBoxCallback(TileBox_Callback), new TileState(TileZType.MapAverage, 0, e.Arguments, outline));
else
e.Mobile.SendMessage("Format: {0}Avg <type> [params] [set {{<propertyName> <value> ...}}]", outline ? "Outline" : "Tile");
}
public class AddTarget : Target
{
private readonly string[] m_Args;
public AddTarget(string[] args)
: base(-1, true, TargetFlags.None)
{
this.m_Args = args;
}
protected override void OnTarget(Mobile from, object o)
{
IPoint3D p = o as IPoint3D;
if (p != null)
{
if (p is Item)
p = ((Item)p).GetWorldTop();
else if (p is Mobile)
p = ((Mobile)p).Location;
Point3D point = new Point3D(p);
Add.Invoke(from, point, point, this.m_Args);
}
}
}
private class TileState
{
public readonly TileZType m_ZType;
public readonly int m_FixedZ;
public readonly string[] m_Args;
public readonly bool m_Outline;
public TileState(TileZType zType, int fixedZ, string[] args, bool outline)
{
this.m_ZType = zType;
this.m_FixedZ = fixedZ;
this.m_Args = args;
this.m_Outline = outline;
}
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
namespace Server
{
public class UsageAttribute : Attribute
{
private readonly string m_Usage;
public UsageAttribute(string usage)
{
this.m_Usage = usage;
}
public string Usage
{
get
{
return this.m_Usage;
}
}
}
public class DescriptionAttribute : Attribute
{
private readonly string m_Description;
public DescriptionAttribute(string description)
{
this.m_Description = description;
}
public string Description
{
get
{
return this.m_Description;
}
}
}
public class AliasesAttribute : Attribute
{
private readonly string[] m_Aliases;
public AliasesAttribute(params string[] aliases)
{
this.m_Aliases = aliases;
}
public string[] Aliases
{
get
{
return this.m_Aliases;
}
}
}
}

476
Scripts/Commands/Batch.cs Normal file
View File

@@ -0,0 +1,476 @@
using System;
using System.Collections;
using System.Reflection;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Network;
namespace Server.Commands
{
public class Batch : BaseCommand
{
private readonly ArrayList m_BatchCommands;
private BaseCommandImplementor m_Scope;
private string m_Condition;
public Batch()
{
this.Commands = new string[] { "Batch" };
this.ListOptimized = true;
this.m_BatchCommands = new ArrayList();
this.m_Condition = "";
}
public BaseCommandImplementor Scope
{
get
{
return this.m_Scope;
}
set
{
this.m_Scope = value;
}
}
public string Condition
{
get
{
return this.m_Condition;
}
set
{
this.m_Condition = value;
}
}
public ArrayList BatchCommands
{
get
{
return this.m_BatchCommands;
}
}
public static void Initialize()
{
CommandSystem.Register("Batch", AccessLevel.Counselor, new CommandEventHandler(Batch_OnCommand));
}
[Usage("Batch")]
[Description("Allows multiple commands to be run at the same time.")]
public static void Batch_OnCommand(CommandEventArgs e)
{
Batch batch = new Batch();
e.Mobile.SendGump(new BatchGump(e.Mobile, batch));
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
if (list.Count == 0)
{
this.LogFailure("Nothing was found to use this command on.");
return;
}
try
{
BaseCommand[] commands = new BaseCommand[this.m_BatchCommands.Count];
CommandEventArgs[] eventArgs = new CommandEventArgs[this.m_BatchCommands.Count];
for (int i = 0; i < this.m_BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)this.m_BatchCommands[i];
string commandString, argString;
string[] args;
bc.GetDetails(out commandString, out argString, out args);
BaseCommand command = this.m_Scope.Commands[commandString];
commands[i] = command;
eventArgs[i] = new CommandEventArgs(e.Mobile, commandString, argString, args);
if (command == null)
{
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier: {0}.", commandString);
return;
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command: {0}.", commandString);
return;
}
else if (!command.ValidateArgs(this.m_Scope, eventArgs[i]))
{
return;
}
}
for (int i = 0; i < commands.Length; ++i)
{
BaseCommand command = commands[i];
BatchCommand bc = (BatchCommand)this.m_BatchCommands[i];
if (list.Count > 20)
CommandLogging.Enabled = false;
ArrayList usedList;
if (Utility.InsensitiveCompare(bc.Object, "Current") == 0)
{
usedList = list;
}
else
{
Hashtable propertyChains = new Hashtable();
usedList = new ArrayList(list.Count);
for (int j = 0; j < list.Count; ++j)
{
object obj = list[j];
if (obj == null)
continue;
Type type = obj.GetType();
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
string failReason = "";
if (chain == null && !propertyChains.Contains(type))
propertyChains[type] = chain = Properties.GetPropertyInfoChain(e.Mobile, type, bc.Object, PropertyAccess.Read, ref failReason);
if (chain == null)
continue;
PropertyInfo endProp = Properties.GetPropertyInfo(ref obj, chain, ref failReason);
if (endProp == null)
continue;
try
{
obj = endProp.GetValue(obj, null);
if (obj != null)
usedList.Add(obj);
}
catch
{
}
}
}
command.ExecuteList(eventArgs[i], usedList);
if (list.Count > 20)
CommandLogging.Enabled = true;
command.Flush(e.Mobile, list.Count > 20);
}
}
catch (Exception ex)
{
e.Mobile.SendMessage(ex.Message);
}
}
public bool Run(Mobile from)
{
if (this.m_Scope == null)
{
from.SendMessage("You must select the batch command scope.");
return false;
}
else if (this.m_Condition.Length > 0 && !this.m_Scope.SupportsConditionals)
{
from.SendMessage("This command scope does not support conditionals.");
return false;
}
else if (this.m_Condition.Length > 0 && !Utility.InsensitiveStartsWith(this.m_Condition, "where"))
{
from.SendMessage("The condition field must start with \"where\".");
return false;
}
string[] args = CommandSystem.Split(this.m_Condition);
this.m_Scope.Process(from, this, args);
return true;
}
}
public class BatchCommand
{
private string m_Command;
private string m_Object;
public BatchCommand(string command, string obj)
{
this.m_Command = command;
this.m_Object = obj;
}
public string Command
{
get
{
return this.m_Command;
}
set
{
this.m_Command = value;
}
}
public string Object
{
get
{
return this.m_Object;
}
set
{
this.m_Object = value;
}
}
public void GetDetails(out string command, out string argString, out string[] args)
{
int indexOf = this.m_Command.IndexOf(' ');
if (indexOf >= 0)
{
argString = this.m_Command.Substring(indexOf + 1);
command = this.m_Command.Substring(0, indexOf);
args = CommandSystem.Split(argString);
}
else
{
argString = "";
command = this.m_Command.ToLower();
args = new string[0];
}
}
}
public class BatchGump : BaseGridGump
{
private readonly Mobile m_From;
private readonly Batch m_Batch;
public BatchGump(Mobile from, Batch batch)
: base(30, 30)
{
this.m_From = from;
this.m_Batch = batch;
this.Render();
}
public void Render()
{
this.AddNewPage();
/* Header */
this.AddEntryHeader(20);
this.AddEntryHtml(180, this.Center("Batch Commands"));
this.AddEntryHeader(20);
this.AddNewLine();
this.AddEntryHeader(9);
this.AddEntryLabel(191, "Run Batch");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, this.GetButtonID(1, 0, 0), ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddBlankLine();
/* Scope */
this.AddEntryHeader(20);
this.AddEntryHtml(180, this.Center("Scope"));
this.AddEntryHeader(20);
this.AddNewLine();
this.AddEntryHeader(9);
this.AddEntryLabel(191, this.m_Batch.Scope == null ? "Select Scope" : this.m_Batch.Scope.Accessors[0]);
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, this.GetButtonID(1, 0, 1), ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddBlankLine();
/* Condition */
this.AddEntryHeader(20);
this.AddEntryHtml(180, this.Center("Condition"));
this.AddEntryHeader(20);
this.AddNewLine();
this.AddEntryHeader(9);
this.AddEntryText(202, 0, this.m_Batch.Condition);
this.AddEntryHeader(9);
this.AddNewLine();
this.AddBlankLine();
/* Commands */
this.AddEntryHeader(20);
this.AddEntryHtml(180, this.Center("Commands"));
this.AddEntryHeader(20);
for (int i = 0; i < this.m_Batch.BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)this.m_Batch.BatchCommands[i];
this.AddNewLine();
this.AddImageTiled(this.CurrentX, this.CurrentY, 9, 2, 0x24A8);
this.AddImageTiled(this.CurrentX, this.CurrentY + 2, 2, this.EntryHeight + this.OffsetSize + this.EntryHeight - 4, 0x24A8);
this.AddImageTiled(this.CurrentX, this.CurrentY + this.EntryHeight + this.OffsetSize + this.EntryHeight - 2, 9, 2, 0x24A8);
this.AddImageTiled(this.CurrentX + 3, this.CurrentY + 3, 6, this.EntryHeight + this.EntryHeight - 4 - this.OffsetSize, this.HeaderGumpID);
this.IncreaseX(9);
this.AddEntryText(202, 1 + (i * 2), bc.Command);
this.AddEntryHeader(9, 2);
this.AddNewLine();
this.IncreaseX(9);
this.AddEntryText(202, 2 + (i * 2), bc.Object);
}
this.AddNewLine();
this.AddEntryHeader(9);
this.AddEntryLabel(191, "Add New Command");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, this.GetButtonID(1, 0, 2), ArrowRightWidth, ArrowRightHeight);
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
int type, index;
if (!this.SplitButtonID(info.ButtonID, 1, out type, out index))
return;
TextRelay entry = info.GetTextEntry(0);
if (entry != null)
this.m_Batch.Condition = entry.Text;
for (int i = this.m_Batch.BatchCommands.Count - 1; i >= 0; --i)
{
BatchCommand sc = (BatchCommand)this.m_Batch.BatchCommands[i];
entry = info.GetTextEntry(1 + (i * 2));
if (entry != null)
sc.Command = entry.Text;
entry = info.GetTextEntry(2 + (i * 2));
if (entry != null)
sc.Object = entry.Text;
if (sc.Command.Length == 0 && sc.Object.Length == 0)
this.m_Batch.BatchCommands.RemoveAt(i);
}
switch ( type )
{
case 0: // main
{
switch ( index )
{
case 0: // run
{
this.m_Batch.Run(this.m_From);
break;
}
case 1: // set scope
{
this.m_From.SendGump(new BatchScopeGump(this.m_From, this.m_Batch));
return;
}
case 2: // add command
{
this.m_Batch.BatchCommands.Add(new BatchCommand("", ""));
break;
}
}
break;
}
}
this.m_From.SendGump(new BatchGump(this.m_From, this.m_Batch));
}
}
public class BatchScopeGump : BaseGridGump
{
private readonly Mobile m_From;
private readonly Batch m_Batch;
public BatchScopeGump(Mobile from, Batch batch)
: base(30, 30)
{
this.m_From = from;
this.m_Batch = batch;
this.Render();
}
public void Render()
{
this.AddNewPage();
/* Header */
this.AddEntryHeader(20);
this.AddEntryHtml(140, this.Center("Change Scope"));
this.AddEntryHeader(20);
/* Options */
for (int i = 0; i < BaseCommandImplementor.Implementors.Count; ++i)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[i];
if (this.m_From.AccessLevel < impl.AccessLevel)
continue;
this.AddNewLine();
this.AddEntryLabel(20 + this.OffsetSize + 140, impl.Accessors[0]);
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, this.GetButtonID(1, 0, i), ArrowRightWidth, ArrowRightHeight);
}
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
int type, index;
if (this.SplitButtonID(info.ButtonID, 1, out type, out index))
{
switch ( type )
{
case 0:
{
if (index < BaseCommandImplementor.Implementors.Count)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[index];
if (this.m_From.AccessLevel >= impl.AccessLevel)
this.m_Batch.Scope = impl;
}
break;
}
}
}
this.m_From.SendGump(new BatchGump(this.m_From, this.m_Batch));
}
}
}

View File

@@ -0,0 +1,68 @@
using System;
using Server.Targeting;
namespace Server
{
public delegate void BoundingBoxCallback(Mobile from, Map map, Point3D start, Point3D end, object state);
public class BoundingBoxPicker
{
public static void Begin(Mobile from, BoundingBoxCallback callback, object state)
{
from.SendMessage("Target the first location of the bounding box.");
from.Target = new PickTarget(callback, state);
}
private class PickTarget : Target
{
private readonly Point3D m_Store;
private readonly bool m_First;
private readonly Map m_Map;
private readonly BoundingBoxCallback m_Callback;
private readonly object m_State;
public PickTarget(BoundingBoxCallback callback, object state)
: this(Point3D.Zero, true, null, callback, state)
{
}
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback, object state)
: base(-1, true, TargetFlags.None)
{
this.m_Store = store;
this.m_First = first;
this.m_Map = map;
this.m_Callback = callback;
this.m_State = state;
}
protected override void OnTarget(Mobile from, object targeted)
{
IPoint3D p = targeted as IPoint3D;
if (p == null)
return;
else if (p is Item)
p = ((Item)p).GetWorldTop();
if (this.m_First)
{
from.SendMessage("Target another location to complete the bounding box.");
from.Target = new PickTarget(new Point3D(p), false, from.Map, this.m_Callback, this.m_State);
}
else if (from.Map != this.m_Map)
{
from.SendMessage("Both locations must reside on the same map.");
}
else if (this.m_Map != null && this.m_Map != Map.Internal && this.m_Callback != null)
{
Point3D start = this.m_Store;
Point3D end = new Point3D(p);
Utility.FixPoints(ref start, ref end);
this.m_Callback(from, this.m_Map, start, end, this.m_State);
}
}
}
}
}

View File

@@ -0,0 +1,647 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Commands;
using Server.Gumps;
using Server.Network;
using System.Linq;
using System.IO;
using Server.Items;
using Server.Mobiles;
namespace Server.Commands
{
public class CreateWorld
{
public enum GumpType
{
Create,
Delete,
Recreate,
}
public enum Category
{
All,
Decoration,
Spawn,
System,
Dungeon,
RevampedDungeon,
Expansion
}
public class CommandEntry
{
public string Name { get; set; }
public string CreateCommand { get; set; }
public string DeleteCommand { get; set; }
public int CheckID { get; set; }
public int Delay { get; set; }
public Category Category { get; set; }
public Expansion RequiredExpansion { get; set; }
public CommandEntry(string n, string c, string d, Category cat, Expansion expansion, int i, int delay = 0)
{
Name = n;
CreateCommand = c;
DeleteCommand = d;
Category = cat;
RequiredExpansion = expansion;
CheckID = i;
Delay = delay;
}
}
public static List<CommandEntry> Commands = new List<CommandEntry>(new CommandEntry[]
{
new CommandEntry("Moongates", "Moongen", "MoonGenDelete", Category.Decoration, Expansion.None, 101),
new CommandEntry("Doors", "DoorGen", "DoorGenDelete", Category.Decoration, Expansion.None, 102),
new CommandEntry("Signs", "SignGen", "SignGenDelete", Category.Decoration, Expansion.None, 103),
new CommandEntry("Teleporters", "TelGen", "TelGenDelete", Category.Decoration, Expansion.None, 104),
new CommandEntry("Doom Lamp", "GenLeverPuzzle", "LampPuzzleDelete", Category.System, Expansion.AOS, 105),
new CommandEntry("Doom Gauntlet", "GenGauntlet", "DeleteGauntlet", Category.Dungeon, Expansion.AOS, 106),
new CommandEntry("Khaldun", "GenKhaldun", "DeleteKhaldun", Category.Dungeon, Expansion.None, 107),
new CommandEntry("Stealables", "GenStealArties", "RemoveStealArties", Category.Spawn, Expansion.AOS, 108),
new CommandEntry("Solen Hives", "SHTelGen", "SHTelGenDelete", Category.Dungeon, Expansion.LBR, 109),
new CommandEntry("Malas Secrets", "SecretLocGen", "SecretLocDelete", Category.System, Expansion.AOS, 110),
new CommandEntry("Factions", "GenerateFactions", "DeleteFactions", Category.System, Expansion.None, 111),
new CommandEntry("Decorations", "Decorate", "DecorateDelete", Category.Decoration, Expansion.None, 113),
new CommandEntry("ML Decorations", "DecorateML", "DecorateMLDelete", Category.Decoration, Expansion.ML, 114),
new CommandEntry("SA Decorations", "DecorateSA", "DecorateSADelete", Category.Decoration, Expansion.SA, 115),
new CommandEntry("Spawners", "XmlLoad Spawns", "WipeAllXmlSpawners", Category.Spawn, Expansion.None, 116),
new CommandEntry("New Despise", "SetupDespise", "DeleteDespise", Category.RevampedDungeon, Expansion.SA, 117),
new CommandEntry("New Covetous", "SetupNewCovetous", "DeleteCovetous", Category.RevampedDungeon, Expansion.SA, 118),
new CommandEntry("New Shame", "GenerateNewShame", "DeleteShame", Category.RevampedDungeon, Expansion.SA, 119),
new CommandEntry("New Magincia", "GenNewMagincia", "DeleteNewMagincia", Category.Decoration, Expansion.None, 120),
new CommandEntry("High Seas", "DecorateHS", "DeleteHS", Category.Expansion, Expansion.HS, 121),
new CommandEntry("City Loyalty", "SetupCityLoyaltySystem","DeleteCityLoyaltySystem",Category.System, Expansion.SA, 122),
new CommandEntry("Castle Blackthorn", "GenBlackthorn", null, Category.RevampedDungeon, Expansion.SA, 123),
new CommandEntry("TOL Decorations", "DecorateTOL", null, Category.Decoration, Expansion.TOL, 124),
new CommandEntry("New Wrong", "GenWrongRevamp", null, Category.RevampedDungeon, Expansion.SA, 125),
new CommandEntry("Kotl City", "GenerateTreasuresOfKotlCity", null, Category.System, Expansion.TOL, 126),
new CommandEntry("Fillable Containers", "CheckFillables", null, Category.Spawn, Expansion.None, 127, 5),
new CommandEntry("Champ Spawns", "GenChampSpawns", "DelChampSpawns", Category.Spawn, Expansion.UOR, 128),
});
public static bool WorldCreating { get; set; }
public CreateWorld()
{
}
public static void Initialize()
{
CommandSystem.Register("Createworld", AccessLevel.Administrator, new CommandEventHandler(Create_OnCommand));
CommandSystem.Register("DeleteWorld", AccessLevel.Administrator, new CommandEventHandler(Delete_OnCommand));
CommandSystem.Register("RecreateWorld", AccessLevel.Administrator, new CommandEventHandler(Recreate_OnCommand));
}
[Usage("CreateWorld [nogump]")]
[Description("Generates the world with a menu. If nogump argument is given, no gump will be displayed, all options will be assumed true, and the action will proceed immediately.")]
private static void Create_OnCommand(CommandEventArgs e)
{
if (String.IsNullOrEmpty(e.ArgString))
{
if (e.Mobile is PlayerMobile)
BaseGump.SendGump(new NewCreateWorldGump((PlayerMobile)e.Mobile, GumpType.Create));
else
e.Mobile.SendGump(new CreateWorldGump(e, GumpType.Create));
}
else if (e.ArgString.ToLower().Equals("nogump"))
{
DoAllCommands(GumpType.Create, e.Mobile);
}
else
{
if (e.Mobile != null)
e.Mobile.SendMessage("Usage: CreateWorld [nogump]");
}
}
[Usage("DeleteWorld [nogump]")]
[Description("Undoes world generation with a menu. If nogump argument is given, no gump will be displayed, all options will be assumed true, and the action will proceed immediately.")]
private static void Delete_OnCommand(CommandEventArgs e)
{
if (String.IsNullOrEmpty(e.ArgString))
{
if (e.Mobile is PlayerMobile)
BaseGump.SendGump(new NewCreateWorldGump((PlayerMobile)e.Mobile, GumpType.Delete));
else
e.Mobile.SendGump(new CreateWorldGump(e, GumpType.Delete));
}
else if (e.ArgString.ToLower().Equals("nogump"))
{
DoAllCommands(GumpType.Delete, e.Mobile);
}
else
{
if (e.Mobile != null)
e.Mobile.SendMessage("Usage: DeleteWorld [nogump]");
}
}
[Usage("RecreateWorld [nogump]")]
[Description("Re-generates the world with a menu. If nogump argument is given, no gump will be displayed, all options will be assumed true, and the action will proceed immediately.")]
private static void Recreate_OnCommand(CommandEventArgs e)
{
if (String.IsNullOrEmpty(e.ArgString))
{
e.Mobile.SendGump(new CreateWorldGump(e, GumpType.Recreate));
}
else if (e.ArgString.ToLower().Equals("nogump"))
{
DoAllCommands(GumpType.Recreate, e.Mobile);
}
else
{
if (e.Mobile != null)
e.Mobile.SendMessage("Usage: RecreateWorld [nogump]");
}
}
public static void DoAllCommands(GumpType type, Mobile from)
{
List<int> ids = new List<int>();
foreach (CommandEntry entry in Commands)
{
ids.Add(entry.CheckID);
}
DoCommands(ids.ToArray(), type, from);
}
public static void DoCommands(int[] selections, GumpType type, Mobile from)
{
World.Broadcast(0x35, false, "The world is generating. This may take some time...");
string prefix = Server.Commands.CommandSystem.Prefix;
string error = null;
WorldCreating = true;
foreach (int sel in selections)
{
foreach (CreateWorld.CommandEntry entry in CreateWorld.Commands)
{
if (entry.CheckID == sel)
{
switch (type)
{
case CreateWorld.GumpType.Create:
from.Say("Generating " + entry.Name);
if (CanGenerate(entry, ref error))
{
if (entry.Delay > 0)
{
DoDelayedCommand(from, TimeSpan.FromMinutes(entry.Delay), prefix + entry.CreateCommand);
}
else
{
CommandSystem.Handle(from, prefix + entry.CreateCommand);
}
if (CreateWorldData.CreateTable.ContainsKey(sel))
CreateWorldData.CreateTable[sel] = true;
}
break;
case CreateWorld.GumpType.Delete:
if (!String.IsNullOrEmpty(entry.DeleteCommand))
{
from.Say("Deleting " + entry.Name);
CommandSystem.Handle(from, prefix + entry.DeleteCommand);
if (CreateWorldData.CreateTable.ContainsKey(sel))
CreateWorldData.CreateTable[sel] = false;
}
break;
}
}
}
}
if (error != null)
{
from.SendGump(new BasicInfoGump(error, "World Generation Error"));
}
WorldCreating = false;
World.Broadcast(0x35, false, "World generation complete.");
}
public static bool CanGenerate(CommandEntry entry, ref string error)
{
if (CreateWorldData.CreateTable.ContainsKey(entry.CheckID) && CreateWorldData.CreateTable[entry.CheckID])
{
string er = String.Format("<br>- {0} have been generated already.", entry.Name);
Console.WriteLine(er);
error += er;
return false;
}
if (entry.CheckID == 127)
{
if (CreateWorldData.HasGenerated(116) && CreateWorldData.HasGenerated(113))
{
return true;
}
string er = String.Format("<br>- Cannot generate {0}. You need to generate Decorations and Spawners first.", entry.Name);
Console.WriteLine(er);
error += er;
return false;
}
if (entry.Category == Category.RevampedDungeon)
{
if (CreateWorldData.HasGenerated(116))
{
return true;
}
else
{
string er = String.Format("<br>- Cannot generate {0}. You need to generate Spawners first.", entry.Name);
Console.WriteLine(er);
error += er;
return false;
}
}
return true;
}
public static void DoDelayedCommand(Mobile from, TimeSpan delay, string command)
{
Console.WriteLine("Setting delayed create command: {0} [{1}] minutes", command, delay.TotalMinutes);
Timer.DelayCall(delay, () =>
{
CommandSystem.Handle(from, command);
});
}
}
}
namespace Server.Gumps
{
public class CreateWorldGump : Gump
{
private readonly CommandEventArgs m_CommandEventArgs;
private CreateWorld.GumpType m_Type;
public CreateWorldGump(CommandEventArgs e, CreateWorld.GumpType type)
: base(50,50)
{
m_Type = type;
m_CommandEventArgs = e;
Closable = true;
Dragable = true;
AddPage(1);
int items = CreateWorld.Commands.Count;
if (!Server.Factions.Settings.Enabled)
items--;
AddBackground(0, 0, 280, 75 + items * 25, 5054);
switch (m_Type)
{
case CreateWorld.GumpType.Create:
AddLabel(40, 2, 200, "CREATE WORLD GUMP");
break;
case CreateWorld.GumpType.Delete:
AddLabel(40, 2, 200, "DELETE WORLD GUMP");
break;
case CreateWorld.GumpType.Recreate:
AddLabel(40, 2, 200, "RECREATE WORLD GUMP");
break;
}
AddImageTiled(10, 20, 220, 10 + items * 25, 3004);
int y = 25;
foreach(CreateWorld.CommandEntry entry in CreateWorld.Commands)
{
if (entry.Name == "Factions" && !Server.Factions.Settings.Enabled)
continue;
bool created = CreateWorldData.CreateTable.ContainsKey(entry.CheckID) && CreateWorldData.CreateTable[entry.CheckID];
AddLabel(20, y + 1, created ? 200 : 338, String.Format("{0} {1}", entry.Name, created ? "[created]" : "[not created]"));
AddCheck(210, y - 2, 210, 211, m_Type == CreateWorld.GumpType.Create ? !created : created, entry.CheckID);
y += 25;
}
y = 25 + (items * 25);
AddButton(60, y + 15, 247, 249, 1, GumpButtonType.Reply, 0);
AddButton(130, y + 15, 241, 243, 0, GumpButtonType.Reply, 0);
}
public override void OnResponse(NetState state, RelayInfo info)
{
Mobile from = state.Mobile;
switch (info.ButtonID)
{
case 0: // Closed or Cancel
return;
case 1:
CreateWorld.DoCommands(info.Switches, m_Type, from);
break;
}
}
}
public class NewCreateWorldGump : BaseGump
{
public CreateWorld.GumpType GumpType { get; set; }
public CreateWorld.Category CategoryFilter { get; set; }
public bool CheckAll { get; set; }
public bool UncheckAll { get; set; }
public NewCreateWorldGump(PlayerMobile pm, CreateWorld.GumpType type)
: base(pm, 50, 50)
{
GumpType = type;
}
public override void AddGumpLayout()
{
AddBackground(0, 0, 640, 500, 5054);
AddImageTiled(10, 10, 140, 28, 3004);
AddImageTiled(152, 10, 478, 28, 3004);
AddImageTiled(10, 40, 140, 430, 3004);
AddImageTiled(152, 40, 478, 430, 3004);
string label = GumpType == CreateWorld.GumpType.Create ? "CREATE WORLD GUMP" : "DELETE WORLD GUMP";
switch (GumpType)
{
default:
case CreateWorld.GumpType.Create:
label = "CREATE WORLD GUMP";
break;
case CreateWorld.GumpType.Delete:
label = "DELETE WORLD GUMP";
break;
}
AddHtml(152, 15, 450, 20, ColorAndCenter("#00FFFF", label), false, false);
AddHtml(12, 15, 140, 20, ColorAndCenter("#696969", String.Format("Your Expansion: {0}", Core.Expansion.ToString())), false, false);
for (int i = 0; i < 6; i++)
{
CreateWorld.Category cat = (CreateWorld.Category)i;
int id = CategoryFilter == cat || CategoryFilter == CreateWorld.Category.All ? 4030 : 4029;
AddButton(12, 55 + (i * 25), id, id == 4030 ? 4029 : 4030, i + 500, GumpButtonType.Reply, 0);
AddHtml(45, 55 + (i * 25), 100, 20, Color("#696969", cat.ToString()), false, false);
}
List<CreateWorld.CommandEntry> commands = new List<CreateWorld.CommandEntry>(CreateWorld.Commands.Where(c =>
CategoryFilter == CreateWorld.Category.All || CategoryFilter == c.Category));
int perpage = CreateWorld.Commands.Count / 2;
int x = 154;
int y = 55;
for (int i = 0; i < commands.Count; i++)
{
var entry = commands[i];
bool created = CreateWorldData.CreateTable[entry.CheckID];
bool meetsExpansion = entry.RequiredExpansion <= Core.Expansion;
bool check;
if (CheckAll)
check = true;
else if (UncheckAll)
check = false;
else
check = GumpType == CreateWorld.GumpType.Create ? !created : created;
if (meetsExpansion)
{
AddLabel(x + 21, y, created ? 200 : 338, String.Format("{0} {1}", entry.Name, created ? "[created]" : "[not created]"));
AddCheck(x, y - 2, 210, 211, check, entry.CheckID);
}
else
{
AddLabel(x + 21, y, created ? 200 : 33, String.Format("{0} {1}", entry.Name, "[Wrong Expansion]"));
AddImage(x, y - 2, 210);
}
y += 20;
if (i == perpage)
{
x = 382;
y = 55;
}
}
AddButton(154, 426, 4005, 4007, 2500, GumpButtonType.Reply, 0);
AddHtml(187, 426, 150, 20, Color("#696969", "Check All"), false, false);
AddButton(154, 448, 4017, 4019, 2501, GumpButtonType.Reply, 0);
AddHtml(187, 448, 150, 20, Color("#696969", "Uncheck All"), false, false);
AddButton(260, 473, 247, 249, 1, GumpButtonType.Reply, 0);
AddButton(323, 473, 241, 243, 0, GumpButtonType.Reply, 0);
}
public override void OnResponse(RelayInfo info)
{
switch (info.ButtonID)
{
case 0: // Closed or Cancel
return;
case 1:
CreateWorld.DoCommands(info.Switches, GumpType, User);
break;
case 2500:
CheckAll = true;
UncheckAll = false;
Refresh();
break;
case 2501:
CheckAll = false;
UncheckAll = true;
Refresh();
break;
default:
int id = info.ButtonID - 500;
if (id >= 0 && id <= 6)
{
CategoryFilter = (CreateWorld.Category)id;
}
Refresh();
break;
}
}
}
public static class CreateWorldData
{
public static Dictionary<int, bool> CreateTable { get; set; }
public static bool HasGenerated(int index)
{
switch (index)
{
case 101:
return PublicMoongate.Moongates.Count > 0;
case 102:
return WeakEntityCollection.HasCollection("door");
case 103:
return WeakEntityCollection.HasCollection("sign");
case 104:
return WeakEntityCollection.HasCollection("tel");
case 105:
return WeakEntityCollection.HasCollection("LeverPuzzleController");
case 106:
return WeakEntityCollection.HasCollection("doom");
case 107:
return WeakEntityCollection.HasCollection("khaldun");
case 108:
return StealableArtifactsSpawner.Instance != null;
case 109:
return SHTeleporter.SHTeleporterCreator.FindSHTeleporter(Map.Trammel, new Point3D(5747, 1895, 0)) != null;
case 110:
return WeakEntityCollection.HasCollection("malas");
case 111:
return WeakEntityCollection.HasCollection("factions");
case 113:
return WeakEntityCollection.HasCollection("deco");
case 114:
return WeakEntityCollection.HasCollection("ml");
case 115:
return WeakEntityCollection.HasCollection("sa");
case 116:
return World.Items.Values.Where(i => i != null && (i is XmlSpawner || i is Spawner)).Count() > 1000;
case 117:
return WeakEntityCollection.HasCollection("despise");
case 118:
return WeakEntityCollection.HasCollection("newcovetous");
case 119:
return WeakEntityCollection.HasCollection("newshame");
case 120:
return Server.Engines.NewMagincia.MaginciaBazaar.Instance != null;
case 121:
return WeakEntityCollection.HasCollection("highseas") || CharydbisSpawner.SpawnInstance != null;
case 122:
return Server.Engines.CityLoyalty.CityLoyaltySystem.Cities != null && Server.Engines.CityLoyalty.CityLoyaltySystem.Cities.Count > 0 && Server.Engines.CityLoyalty.CityLoyaltySystem.Cities[0].Stone != null;
case 123:
return HasItem(typeof(DungeonHitchingPost), new Point3D(6428, 2677, 0), Map.Trammel) &&
HasItem(typeof(DungeonHitchingPost), new Point3D(6428, 2677, 0), Map.Felucca);
case 124:
return WeakEntityCollection.HasCollection("tol");
case 125:
return BedrollSpawner.Instances != null && BedrollSpawner.Instances.Count > 0;
case 126:
return Server.Engines.TreasuresOfKotlCity.KotlBattleSimulator.Instance != null;
case 128:
return Server.Engines.CannedEvil.ChampionSystem.AllSpawns.Count > 0;
}
return false;
}
public static bool HasItem(Type type, Point3D p, Map map)
{
IPooledEnumerable eable = map.GetItemsInRange(p, 0);
foreach (Item item in eable)
{
if (item.GetType() == type)
{
eable.Free();
return true;
}
}
eable.Free();
return false;
}
public static void Initialize()
{
if (!_HasRan)
{
CreateTable = new Dictionary<int, bool>();
foreach (CreateWorld.CommandEntry entry in CreateWorld.Commands)
{
CreateTable[entry.CheckID] = HasGenerated(entry.CheckID);
}
}
}
public static readonly string FilePath = Path.Combine("Saves/Misc", "Persistence.bin");
private static bool _HasRan;
public static void Configure()
{
EventSink.WorldSave += OnSave;
EventSink.WorldLoad += OnLoad;
}
public static void OnSave(WorldSaveEventArgs e)
{
Persistence.Serialize(
FilePath,
writer =>
{
writer.Write(1);
writer.Write(true);
writer.Write(CreateTable.Count);
foreach (var kvp in CreateTable)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
});
}
public static void OnLoad()
{
Persistence.Deserialize(
FilePath,
reader =>
{
int version = reader.ReadInt();
_HasRan = reader.ReadBool();
CreateTable = new Dictionary<int, bool>();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
CreateTable[reader.ReadInt()] = reader.ReadBool();
}
if (version == 0)
{
CreateTable[128] = HasGenerated(128);
}
});
}
}
}

1417
Scripts/Commands/Decorate.cs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
using System;
using Server.Commands;
using Server.Items;
namespace Server
{
public static class StygianAbyss
{
public static void Initialize()
{
CommandSystem.Register("DecorateSA", AccessLevel.Administrator, new CommandEventHandler(DecorateSA_OnCommand));
CommandSystem.Register("DecorateSADelete", AccessLevel.Administrator, new CommandEventHandler(DecorateSADelete_OnCommand));
}
[Usage("DecorateSADelete")]
[Description("Deletes Stygian Abyss world decoration.")]
private static void DecorateSADelete_OnCommand(CommandEventArgs e)
{
WeakEntityCollection.Delete("sa");
Server.Engines.ExploringTheDeep.GenerateExploringTheDeep.Delete(e);
SpawnerPersistence.RemoveSpawnsFromXmlFile("Spawns", "GravewaterLake");
}
[Usage("DecorateSA")]
[Description("Generates Stygian Abyss world decoration.")]
private static void DecorateSA_OnCommand(CommandEventArgs e)
{
e.Mobile.SendMessage("Generating Stygian Abyss world decoration, please wait.");
Decorate.Generate("sa", "Data/Decoration/Stygian Abyss/Ter Mur", Map.TerMur);
Decorate.Generate("sa", "Data/Decoration/Stygian Abyss/Trammel", Map.Trammel);
Decorate.Generate("sa", "Data/Decoration/Stygian Abyss/Felucca", Map.Felucca);
NavreysController.GenNavery(e.Mobile);
CommandSystem.Handle(e.Mobile, Server.Commands.CommandSystem.Prefix + "GenToK");
CommandSystem.Handle(e.Mobile, Server.Commands.CommandSystem.Prefix + "GenSutek");
GenerateUnderworldRooms.Generate();
Server.Engines.ResortAndCasino.FireCasinoGenerator.Generate(e);
Server.Engines.ExploringTheDeep.GenerateExploringTheDeep.Generate(e);
e.Mobile.SendMessage("Stygian Abyss world generation complete.");
}
}
}

3158
Scripts/Commands/Docs.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,563 @@
using System;
using System.Collections.Generic;
using Server.Commands;
using Server.Items;
namespace Server
{
public class DoorGeneratorDelete
{
private static readonly Rectangle2D[] m_BritRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(250, 750), new Point2D(775, 1330)),
new Rectangle2D(new Point2D(525, 2095), new Point2D(925, 2430)),
new Rectangle2D(new Point2D(1025, 2155), new Point2D(1265, 2310)),
new Rectangle2D(new Point2D(1635, 2430), new Point2D(1705, 2508)),
new Rectangle2D(new Point2D(1775, 2605), new Point2D(2165, 2975)),
new Rectangle2D(new Point2D(1055, 3520), new Point2D(1570, 4075)),
new Rectangle2D(new Point2D(2860, 3310), new Point2D(3120, 3630)),
new Rectangle2D(new Point2D(2470, 1855), new Point2D(3950, 3045)),
new Rectangle2D(new Point2D(3425, 990), new Point2D(3900, 1455)),
new Rectangle2D(new Point2D(4175, 735), new Point2D(4840, 1600)),
new Rectangle2D(new Point2D(2375, 330), new Point2D(3100, 1045)),
new Rectangle2D(new Point2D(2100, 1090), new Point2D(2310, 1450)),
new Rectangle2D(new Point2D(1495, 1400), new Point2D(1550, 1475)),
new Rectangle2D(new Point2D(1085, 1520), new Point2D(1415, 1910)),
new Rectangle2D(new Point2D(1410, 1500), new Point2D(1745, 1795)),
new Rectangle2D(new Point2D(5120, 2300), new Point2D(6143, 4095))
};
private static readonly Rectangle2D[] m_IlshRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(0, 0), new Point2D(288 * 8, 200 * 8))
};
private static readonly Rectangle2D[] m_MalasRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(0, 0), new Point2D(320 * 8, 256 * 8))
};
private static readonly int[] m_SouthFrames = new int[]
{
0x0006,
0x0008,
0x000B,
0x001A,
0x001B,
0x001F,
0x0038,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AA,
0x00AE,
0x00B0,
0x00B3,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0204,
0x0206,
0x0208,
0x020A
};
private static readonly int[] m_NorthFrames = new int[]
{
0x0006,
0x0008,
0x000D,
0x001A,
0x001B,
0x0020,
0x003A,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AC,
0x00AE,
0x00B0,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0201,
0x0204,
0x0208,
0x020A
};
private static readonly int[] m_EastFrames = new int[]
{
0x0007,
0x000A,
0x001A,
0x001C,
0x001E,
0x0037,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AB,
0x00AE,
0x00AF,
0x00B2,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012B,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0203,
0x0205,
0x0207,
0x0209
};
private static readonly int[] m_WestFrames = new int[]
{
0x0007,
0x000C,
0x001A,
0x001C,
0x0021,
0x0039,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AD,
0x00AE,
0x00AF,
0x00B5,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0200,
0x0203,
0x0207,
0x0209
};
private static Map m_Map;
private static int m_Count;
public static void Initialize()
{
CommandSystem.Register("DoorGenDelete", AccessLevel.Administrator, new CommandEventHandler(DoorGenDelete_OnCommand));
}
[Usage("DoorGenDelete")]
[Description("Deletes doors by analyzing the map.")]
public static void DoorGenDelete_OnCommand(CommandEventArgs e)
{
WeakEntityCollection.Delete("door");
// Retained for backward compatibility
Delete();
}
public static void Delete()
{
World.Broadcast(0x35, true, "Deleting doors, please wait.");
Network.NetState.FlushAll();
Network.NetState.Pause();
m_Map = Map.Trammel;
m_Count = 0;
for (int i = 0; i < m_BritRegions.Length; ++i)
Delete(m_BritRegions[i]);
int trammelCount = m_Count;
m_Map = Map.Felucca;
m_Count = 0;
for (int i = 0; i < m_BritRegions.Length; ++i)
Delete(m_BritRegions[i]);
int feluccaCount = m_Count;
m_Map = Map.Ilshenar;
m_Count = 0;
for (int i = 0; i < m_IlshRegions.Length; ++i)
Delete(m_IlshRegions[i]);
int ilshenarCount = m_Count;
m_Map = Map.Malas;
m_Count = 0;
for (int i = 0; i < m_MalasRegions.Length; ++i)
Delete(m_MalasRegions[i]);
int malasCount = m_Count;
Network.NetState.Resume();
World.Broadcast(0x35, true, "Door deletion complete. Trammel: {0}; Felucca: {1}; Ilshenar: {2}; Malas: {3};", trammelCount, feluccaCount, ilshenarCount, malasCount);
}
public static void DeleteDoor(int x, int y, int z)
{
int doorZ = z;
int doorTop = doorZ + 20;
m_Count += DeleteBaseDoor(m_Map, new Point3D(x, y, z));
}
public static void Delete(Rectangle2D region)
{
for (int rx = 0; rx < region.Width; ++rx)
{
for (int ry = 0; ry < region.Height; ++ry)
{
int vx = rx + region.X;
int vy = ry + region.Y;
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(vx, vy);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
int id = tile.ID;
int z = tile.Z;
if (IsWestFrame(id))
{
if (IsEastFrame(vx + 2, vy, z))
{
DeleteDoor(vx + 1, vy, z);
}
else if (IsEastFrame(vx + 3, vy, z))
{
/*BaseDoor first = */DeleteDoor(vx + 1, vy, z);
/*BaseDoor second = */DeleteDoor(vx + 2, vy, z);
/*if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
if (first != null)
first.Delete();
if (second != null)
second.Delete();
}*/
}
}
else if (IsNorthFrame(id))
{
if (IsSouthFrame(vx, vy + 2, z))
{
DeleteDoor(vx, vy + 1, z);
}
else if (IsSouthFrame(vx, vy + 3, z))
{
/*BaseDoor first = */DeleteDoor(vx, vy + 1, z);
/*BaseDoor second = */DeleteDoor(vx, vy + 2, z);
/*if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
if (first != null)
first.Delete();
if (second != null)
second.Delete();
}*/
}
}
}
}
}
}
public static bool IsFrame(int id, int[] list)
{
id &= 0x3FFF;
if (id > list[list.Length - 1])
return false;
for (int i = 0; i < list.Length; ++i)
{
int delta = id - list[i];
if (delta < 0)
return false;
else if (delta == 0)
return true;
}
return false;
}
public static bool IsNorthFrame(int id)
{
return IsFrame(id, m_NorthFrames);
}
public static bool IsSouthFrame(int id)
{
return IsFrame(id, m_SouthFrames);
}
public static bool IsWestFrame(int id)
{
return IsFrame(id, m_WestFrames);
}
public static bool IsEastFrame(int id)
{
return IsFrame(id, m_EastFrames);
}
public static bool IsEastFrame(int x, int y, int z)
{
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
if (tile.Z == z && IsEastFrame(tile.ID))
return true;
}
return false;
}
public static bool IsSouthFrame(int x, int y, int z)
{
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
if (tile.Z == z && IsSouthFrame(tile.ID))
return true;
}
return false;
}
private static int DeleteBaseDoor(Map map, Point3D p)
{
Queue<Item> m_Queue = new Queue<Item>();
IPooledEnumerable eable = map.GetItemsInRange(p, 0);
foreach (Item item in eable)
{
if (item is BaseDoor)
{
int delta = item.Z - p.Z;
if (delta >= -12 && delta <= 12)
m_Queue.Enqueue(item);
}
}
eable.Free();
int count = m_Queue.Count;
while (m_Queue.Count > 0)
(m_Queue.Dequeue()).Delete();
return count;
}
}
}

View File

@@ -0,0 +1,556 @@
using System;
using Server.Commands;
using Server.Items;
namespace Server
{
public class DoorGenerator
{
private static readonly Rectangle2D[] m_BritRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(250, 750), new Point2D(775, 1330)),
new Rectangle2D(new Point2D(525, 2095), new Point2D(925, 2430)),
new Rectangle2D(new Point2D(1025, 2155), new Point2D(1265, 2310)),
new Rectangle2D(new Point2D(1635, 2430), new Point2D(1705, 2508)),
new Rectangle2D(new Point2D(1775, 2605), new Point2D(2165, 2975)),
new Rectangle2D(new Point2D(1055, 3520), new Point2D(1570, 4075)),
new Rectangle2D(new Point2D(2860, 3310), new Point2D(3120, 3630)),
new Rectangle2D(new Point2D(2470, 1855), new Point2D(3950, 3045)),
new Rectangle2D(new Point2D(3425, 990), new Point2D(3900, 1455)),
new Rectangle2D(new Point2D(4175, 735), new Point2D(4840, 1600)),
new Rectangle2D(new Point2D(2375, 330), new Point2D(3100, 1045)),
new Rectangle2D(new Point2D(2100, 1090), new Point2D(2310, 1450)),
new Rectangle2D(new Point2D(1495, 1400), new Point2D(1550, 1475)),
new Rectangle2D(new Point2D(1085, 1520), new Point2D(1415, 1910)),
new Rectangle2D(new Point2D(1410, 1500), new Point2D(1745, 1795)),
new Rectangle2D(new Point2D(5120, 2300), new Point2D(6143, 4095))
};
private static readonly Rectangle2D[] m_IlshRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(0, 0), new Point2D(288 * 8, 200 * 8))
};
private static readonly Rectangle2D[] m_MalasRegions = new Rectangle2D[]
{
new Rectangle2D(new Point2D(0, 0), new Point2D(320 * 8, 256 * 8))
};
private static readonly int[] m_SouthFrames = new int[]
{
0x0006,
0x0008,
0x000B,
0x001A,
0x001B,
0x001F,
0x0038,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AA,
0x00AE,
0x00B0,
0x00B3,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0204,
0x0206,
0x0208,
0x020A
};
private static readonly int[] m_NorthFrames = new int[]
{
0x0006,
0x0008,
0x000D,
0x001A,
0x001B,
0x0020,
0x003A,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AC,
0x00AE,
0x00B0,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0201,
0x0204,
0x0208,
0x020A
};
private static readonly int[] m_EastFrames = new int[]
{
0x0007,
0x000A,
0x001A,
0x001C,
0x001E,
0x0037,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AB,
0x00AE,
0x00AF,
0x00B2,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012B,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0203,
0x0205,
0x0207,
0x0209
};
private static readonly int[] m_WestFrames = new int[]
{
0x0007,
0x000C,
0x001A,
0x001C,
0x0021,
0x0039,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AD,
0x00AE,
0x00AF,
0x00B5,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0200,
0x0203,
0x0207,
0x0209
};
private static Map m_Map;
private static int m_Count;
public static void Initialize()
{
CommandSystem.Register("DoorGen", AccessLevel.Administrator, new CommandEventHandler(DoorGen_OnCommand));
}
[Usage("DoorGen")]
[Description("Generates doors by analyzing the map. Slow.")]
public static void DoorGen_OnCommand(CommandEventArgs e)
{
Generate();
}
public static void Generate()
{
World.Broadcast(0x35, true, "Generating doors, please wait.");
Network.NetState.FlushAll();
Network.NetState.Pause();
m_Map = Map.Trammel;
m_Count = 0;
for (int i = 0; i < m_BritRegions.Length; ++i)
Generate(m_BritRegions[i]);
int trammelCount = m_Count;
m_Map = Map.Felucca;
m_Count = 0;
for (int i = 0; i < m_BritRegions.Length; ++i)
Generate(m_BritRegions[i]);
int feluccaCount = m_Count;
m_Map = Map.Ilshenar;
m_Count = 0;
for (int i = 0; i < m_IlshRegions.Length; ++i)
Generate(m_IlshRegions[i]);
int ilshenarCount = m_Count;
m_Map = Map.Malas;
m_Count = 0;
for (int i = 0; i < m_MalasRegions.Length; ++i)
Generate(m_MalasRegions[i]);
int malasCount = m_Count;
Network.NetState.Resume();
World.Broadcast(0x35, true, "Door generation complete. Trammel: {0}; Felucca: {1}; Ilshenar: {2}; Malas: {3};", trammelCount, feluccaCount, ilshenarCount, malasCount);
}
public static bool IsFrame(int id, int[] list)
{
if (id > list[list.Length - 1])
return false;
for (int i = 0; i < list.Length; ++i)
{
int delta = id - list[i];
if (delta < 0)
return false;
else if (delta == 0)
return true;
}
return false;
}
public static bool IsNorthFrame(int id)
{
return IsFrame(id, m_NorthFrames);
}
public static bool IsSouthFrame(int id)
{
return IsFrame(id, m_SouthFrames);
}
public static bool IsWestFrame(int id)
{
return IsFrame(id, m_WestFrames);
}
public static bool IsEastFrame(int id)
{
return IsFrame(id, m_EastFrames);
}
public static bool IsEastFrame(int x, int y, int z)
{
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
if (tile.Z == z && IsEastFrame(tile.ID))
return true;
}
return false;
}
public static bool IsSouthFrame(int x, int y, int z)
{
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
if (tile.Z == z && IsSouthFrame(tile.ID))
return true;
}
return false;
}
public static BaseDoor AddDoor(int x, int y, int z, DoorFacing facing)
{
int doorZ = z;
int doorTop = doorZ + 20;
if (!m_Map.CanFit(x, y, z, 16, false, false))
return null;
if (y == 1743 && x >= 1343 && x <= 1344)
return null;
if (y == 1679 && x >= 1392 && x <= 1393)
return null;
if (x == 1320 && y >= 1618 && y <= 1640)
return null;
if (x == 1383 && y >= 1642 && y <= 1643)
return null;
BaseDoor door = new DarkWoodDoor(facing);
WeakEntityCollection.Add("door", door);
door.MoveToWorld(new Point3D(x, y, z), m_Map);
++m_Count;
return door;
}
public static void Generate(Rectangle2D region)
{
for (int rx = 0; rx < region.Width; ++rx)
{
for (int ry = 0; ry < region.Height; ++ry)
{
int vx = rx + region.X;
int vy = ry + region.Y;
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(vx, vy);
for (int i = 0; i < tiles.Length; ++i)
{
StaticTile tile = tiles[i];
int id = tile.ID;
int z = tile.Z;
if (IsWestFrame(id))
{
if (IsEastFrame(vx + 2, vy, z))
{
AddDoor(vx + 1, vy, z, DoorFacing.WestCW);
}
else if (IsEastFrame(vx + 3, vy, z))
{
BaseDoor first = AddDoor(vx + 1, vy, z, DoorFacing.WestCW);
BaseDoor second = AddDoor(vx + 2, vy, z, DoorFacing.EastCCW);
if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
if (first != null)
first.Delete();
if (second != null)
second.Delete();
}
}
}
else if (IsNorthFrame(id))
{
if (IsSouthFrame(vx, vy + 2, z))
{
AddDoor(vx, vy + 1, z, DoorFacing.SouthCW);
}
else if (IsSouthFrame(vx, vy + 3, z))
{
BaseDoor first = AddDoor(vx, vy + 1, z, DoorFacing.NorthCCW);
BaseDoor second = AddDoor(vx, vy + 2, z, DoorFacing.SouthCW);
if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
if (first != null)
first.Delete();
if (second != null)
second.Delete();
}
}
}
}
}
}
}
}
}

357
Scripts/Commands/Dupe.cs Normal file
View File

@@ -0,0 +1,357 @@
#region References
using System;
using System.Linq;
using Server.Items;
using Server.Targeting;
#endregion
namespace Server.Commands
{
public class Dupe
{
public static void Initialize()
{
CommandSystem.Register("Dupe", AccessLevel.GameMaster, Dupe_OnCommand);
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand);
}
[Usage("Dupe [amount]")]
[Description("Dupes a targeted item.")]
private static void Dupe_OnCommand(CommandEventArgs e)
{
var amount = 1;
if (e.Length > 0)
{
amount = e.GetInt32(0);
}
e.Mobile.Target = new DupeTarget(false, Math.Max(1, amount));
e.Mobile.SendMessage("What do you wish to dupe?");
}
[Usage("DupeInBag <count>")]
[Description("Dupes an item at it's current location (count) number of times.")]
private static void DupeInBag_OnCommand(CommandEventArgs e)
{
var amount = 1;
if (e.Length > 0)
{
amount = e.GetInt32(0);
}
e.Mobile.Target = new DupeTarget(true, Math.Max(1, amount));
e.Mobile.SendMessage("What do you wish to dupe?");
}
private class DupeTarget : Target
{
private readonly bool _InBag;
private readonly int _Amount;
public DupeTarget(bool inbag, int amount)
: base(15, false, TargetFlags.None)
{
_InBag = inbag;
_Amount = amount;
}
protected override void OnTarget(Mobile m, object targ)
{
var done = false;
if (!(targ is Item))
{
m.SendMessage("You can only dupe items.");
return;
}
CommandLogging.WriteLine(
m,
"{0} {1} duping {2} (inBag={3}; amount={4})",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(targ),
_InBag,
_Amount);
var item = (Item)targ;
Container pack;
if (_InBag)
{
if (item.Parent is Container)
{
pack = (Container)item.Parent;
}
else if (item.Parent is Mobile)
{
pack = ((Mobile)item.Parent).Backpack;
}
else
{
pack = null;
}
}
else
{
pack = m.Backpack;
}
var t = item.GetType();
var a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
return;
}
try
{
m.SendMessage("Duping {0}...", _Amount);
var noCtor = false;
for (var i = 0; i < _Amount; i++)
{
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
noCtor = true;
break;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
m.SendMessage("Duping Container Children...");
DupeChildren(m, (Container)item, (Container)o);
}
if (pack != null)
{
pack.DropItem(o);
}
else
{
o.MoveToWorld(m.Location, m.Map);
}
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(
m,
"{0} {1} duped {2} creating {3}",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(item),
CommandLogging.Format(o));
}
if (!noCtor)
{
m.SendMessage("Done");
done = true;
}
}
catch(Exception e)
{
Console.WriteLine(e.StackTrace);
m.SendMessage("Error!");
return;
}
if (!done)
{
m.SendMessage("Unable to dupe. Item must have a 0 parameter constructor.");
}
else
{
item.Delta(ItemDelta.Update);
}
}
}
public static Item DupeItem(Item item)
{
return DupeItem(null, item);
}
public static Item DupeItem(Mobile m, Item item)
{
try
{
var t = item.GetType();
if (m != null)
{
var a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
return null;
}
}
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
return null;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
DupeChildren(m, (Container)item, (Container)o);
}
if (m != null)
{
o.MoveToWorld(m.Location, m.Map);
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(m, "{0} {1} duped {2} creating {3}", m.AccessLevel, CommandLogging.Format(m),
CommandLogging.Format(item), CommandLogging.Format(o));
}
item.Delta(ItemDelta.Update);
return o;
}
catch
{
return null;
}
}
public static void DupeChildren(Container src, Container dest)
{
DupeChildren(null, src, dest);
}
public static void DupeChildren(Mobile m, Container src, Container dest)
{
foreach (var item in src.Items)
{
try
{
var t = item.GetType();
if (m != null)
{
var a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
continue;
}
}
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
continue;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
DupeChildren(m, (Container)item, (Container)o);
}
dest.DropItem(o);
o.Location = item.Location;
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(
m,
"{0} {1} duped {2} creating {3}",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(item),
CommandLogging.Format(o));
item.Delta(ItemDelta.Update);
}
catch
{ }
}
}
public static void CopyProperties(object src, object dest)
{
var props = src.GetType().GetProperties();
foreach (var p in props)
{
try
{
if (p.CanRead && p.CanWrite)
{
p.SetValue(dest, p.GetValue(src, null), null);
}
}
catch
{ }
}
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections;
using System.IO;
using Server.Items;
namespace Server.Commands
{
public class ExportCommand
{
private const string ExportFile = @"C:\Uo\WorldForge\items.wsc";
public static void Initialize()
{
CommandSystem.Register("ExportWSC", AccessLevel.Administrator, new CommandEventHandler(Export_OnCommand));
}
public static void Export_OnCommand(CommandEventArgs e)
{
StreamWriter w = new StreamWriter(ExportFile);
ArrayList remove = new ArrayList();
int count = 0;
e.Mobile.SendMessage("Exporting all static items to \"{0}\"...", ExportFile);
e.Mobile.SendMessage("This will delete all static items in the world. Please make a backup.");
foreach (Item item in World.Items.Values)
{
if ((item is Static || item is BaseFloor || item is BaseWall) &&
item.RootParent == null)
{
w.WriteLine("SECTION WORLDITEM {0}", count);
w.WriteLine("{");
w.WriteLine("SERIAL {0}", item.Serial);
w.WriteLine("NAME #");
w.WriteLine("NAME2 #");
w.WriteLine("ID {0}", item.ItemID);
w.WriteLine("X {0}", item.X);
w.WriteLine("Y {0}", item.Y);
w.WriteLine("Z {0}", item.Z);
w.WriteLine("COLOR {0}", item.Hue);
w.WriteLine("CONT -1");
w.WriteLine("TYPE 0");
w.WriteLine("AMOUNT 1");
w.WriteLine("WEIGHT 255");
w.WriteLine("OWNER -1");
w.WriteLine("SPAWN -1");
w.WriteLine("VALUE 1");
w.WriteLine("}");
w.WriteLine("");
count++;
remove.Add(item);
w.Flush();
}
}
w.Close();
foreach (Item item in remove)
item.Delete();
e.Mobile.SendMessage("Export complete. Exported {0} statics.", count);
}
}
}
/*SECTION WORLDITEM 1
{
SERIAL 1073741830
NAME #
NAME2 #
ID 1709
X 1439
Y 1613
Z 20
CONT -1
TYPE 12
AMOUNT 1
WEIGHT 25500
OWNER -1
SPAWN -1
VALUE 1
}*/

198
Scripts/Commands/GMbody.cs Normal file
View File

@@ -0,0 +1,198 @@
using System;
using System.Collections;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Commands
{
public class GMbody
{
public static void Initialize()
{
CommandSystem.Register("GMbody", AccessLevel.Counselor, new CommandEventHandler(GM_OnCommand));
}
[Usage("GMbody")]
[Description("Helps staff members get going.")]
public static void GM_OnCommand(CommandEventArgs e)
{
e.Mobile.Target = new GMmeTarget();
}
private class GMmeTarget : Target
{
private static Mobile m_Mobile;
public GMmeTarget()
: base(-1, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
if (from != targ)
from.SendMessage("You may only set your own body to GM style.");
else
{
m_Mobile = from;
if (Config.Get("Staff.Staffbody", true))
{
m_Mobile.BodyValue = 987;
if (Config.Get("Staff.UseColoring", true))
{
switch (m_Mobile.AccessLevel)
{
case AccessLevel.Owner:m_Mobile.Hue = Config.Get("Staff.Owner", 1001); break;
case AccessLevel.Developer:m_Mobile.Hue = Config.Get("Staff.Developer", 1001); break;
case AccessLevel.Administrator: m_Mobile.Hue = Config.Get("Staff.Administrator", 1001); break;
case AccessLevel.Seer: m_Mobile.Hue = Config.Get("Staff.Seer", 467); break;
case AccessLevel.GameMaster: m_Mobile.Hue = Config.Get("Staff.GameMaster", 39); break;
case AccessLevel.Counselor: m_Mobile.Hue = Config.Get("Staff.Counselor", 3); break;
}
}
}
if (Config.Get("Staff.CutHair", true))
m_Mobile.HairItemID = 0;
if (Config.Get("Staff.CutFacialHair", true))
m_Mobile.FacialHairItemID = 0;
CommandLogging.WriteLine(from, "{0} {1} is assuming a GM body", from.AccessLevel, CommandLogging.Format(from));
Container pack = from.Backpack;
ArrayList ItemsToDelete = new ArrayList();
foreach (Item item in from.Items)
{
if (item.Layer != Layer.Bank && item.Layer != Layer.Hair && item.Layer != Layer.FacialHair && item.Layer != Layer.Mount && item.Layer != Layer.Backpack)
{
ItemsToDelete.Add(item);
}
}
foreach (Item item in ItemsToDelete)
item.Delete();
if (pack == null)
{
pack = new Backpack();
pack.Movable = false;
from.AddItem(pack);
}
else
{
pack.Delete();
pack = new Backpack();
pack.Movable = false;
from.AddItem(pack);
}
from.Hunger = 20;
from.Thirst = 20;
from.Fame = 0;
from.Karma = 0;
from.Kills = 0;
from.Hidden = true;
from.Blessed = true;
from.Hits = from.HitsMax;
from.Mana = from.ManaMax;
from.Stam = from.StamMax;
if (from.IsStaff())
{
EquipItem(new StaffRing());
PackItem(new GMHidingStone());
PackItem(new GMEthereal());
PackItem(new StaffOrb());
from.RawStr = 100;
from.RawDex = 100;
from.RawInt = 100;
from.Hits = from.HitsMax;
from.Mana = from.ManaMax;
from.Stam = from.StamMax;
for (int i = 0; i < targ.Skills.Length; ++i)
targ.Skills[i].Base = 120;
}
if (Config.Get("Staff.GiveBoots", true))
{
int color = 0;
if (Config.Get("Staff.UseColoring", true))
{
switch (m_Mobile.AccessLevel)
{
case AccessLevel.Owner: color = Config.Get("Staff.Owner", 1001); break;
case AccessLevel.Developer: color = Config.Get("Staff.Developer", 1001); break;
case AccessLevel.Administrator: color = Config.Get("Staff.Administrator", 1001); break;
case AccessLevel.Seer: color = Config.Get("Staff.Seer", 467); break;
case AccessLevel.GameMaster: color = Config.Get("Staff.GameMaster", 39); break;
case AccessLevel.Counselor: color = Config.Get("Staff.Counselor", 3); break;
}
}
if (from.IsStaff() && from.AccessLevel <= AccessLevel.Spawner)
EquipItem(new FurBoots(color));
else if (from.AccessLevel == AccessLevel.GameMaster)
EquipItem(new FurBoots(color));
if (from.AccessLevel == AccessLevel.Seer)
EquipItem(new FurBoots(color));
if (from.AccessLevel == AccessLevel.Administrator)
EquipItem(new FurBoots(color));
if (from.AccessLevel == AccessLevel.Developer)
EquipItem(new FurBoots(color));
if (from.AccessLevel >= AccessLevel.CoOwner)
EquipItem(new FurBoots(color));
}
}
}
}
private static void EquipItem(Item item)
{
EquipItem(item, false);
}
private static void EquipItem(Item item, bool mustEquip)
{
if (!Core.AOS)
item.LootType = LootType.Blessed;
if (m_Mobile != null && m_Mobile.EquipItem(item))
return;
Container pack = m_Mobile.Backpack;
if (!mustEquip && pack != null)
pack.DropItem(item);
else
item.Delete();
}
private static void PackItem(Item item)
{
if (!Core.AOS)
item.LootType = LootType.Blessed;
Container pack = m_Mobile.Backpack;
if (pack != null)
pack.DropItem(item);
else
item.Delete();
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.IO;
using Server.Commands;
namespace Server.Bounds
{
public class Bounds
{
public static void Initialize()
{
CommandSystem.Register("GenBounds", AccessLevel.Administrator, new CommandEventHandler(GenBounds_OnCommand));
}
[Usage("GenBounds")]
[Description("GenBounds")]
public static void GenBounds_OnCommand(CommandEventArgs e)
{
if(Ultima.Files.MulPath["artlegacymul.uop"] != null || (Ultima.Files.MulPath["art.mul"] != null && Ultima.Files.MulPath["artidx.mul"] != null))
{
Utility.PushColor(ConsoleColor.Yellow);
Console.Write("Generating Bounds.bin...");
Utility.PopColor();
FileStream fs = new FileStream( "Data/Binary/Bounds.bin", FileMode.Create, FileAccess.Write );
BinaryWriter bin = new BinaryWriter( fs );
int xMin, yMin, xMax, yMax;
for ( int i = 0; i < Ultima.Art.GetMaxItemID(); ++i )
{
Ultima.Art.Measure(Item.GetBitmap(i), out xMin, out yMin, out xMax, out yMax);
bin.Write((ushort)xMin);
bin.Write((ushort)yMin);
bin.Write((ushort)xMax);
bin.Write((ushort)yMax);
}
Utility.PushColor(ConsoleColor.Green);
Console.WriteLine("done");
Utility.PopColor();
bin.Close();
}
else
{
Utility.PushColor(ConsoleColor.Red);
Console.WriteLine("Art files missing.");
Utility.PopColor();
}
}
}
}

View File

@@ -0,0 +1,469 @@
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Xml;
using Server.Items;
namespace Server.Commands
{
public class Categorization
{
private static readonly Type typeofItem = typeof(Item);
private static readonly Type typeofMobile = typeof(Mobile);
private static readonly Type typeofConstructable = typeof(ConstructableAttribute);
private static CategoryEntry m_RootItems, m_RootMobiles;
public static CategoryEntry Items
{
get
{
if (m_RootItems == null)
Load();
return m_RootItems;
}
}
public static CategoryEntry Mobiles
{
get
{
if (m_RootMobiles == null)
Load();
return m_RootMobiles;
}
}
public static void Initialize()
{
CommandSystem.Register("RebuildCategorization", AccessLevel.Administrator, new CommandEventHandler(RebuildCategorization_OnCommand));
}
[Usage("RebuildCategorization")]
[Description("Rebuilds the categorization data file used by the Add command.")]
public static void RebuildCategorization_OnCommand(CommandEventArgs e)
{
CategoryEntry root = new CategoryEntry(null, "Add Menu", new CategoryEntry[] { Items, Mobiles });
Export(root, "Data/objects.xml", "Objects");
e.Mobile.SendMessage("Categorization menu rebuilt.");
}
public static void RecurseFindCategories(CategoryEntry ce, ArrayList list)
{
list.Add(ce);
for (int i = 0; i < ce.SubCategories.Length; ++i)
RecurseFindCategories(ce.SubCategories[i], list);
}
public static void Export(CategoryEntry ce, string fileName, string title)
{
XmlTextWriter xml = new XmlTextWriter(fileName, System.Text.Encoding.UTF8);
xml.Indentation = 1;
xml.IndentChar = '\t';
xml.Formatting = Formatting.Indented;
xml.WriteStartDocument(true);
RecurseExport(xml, ce);
xml.Flush();
xml.Close();
}
public static void RecurseExport(XmlTextWriter xml, CategoryEntry ce)
{
xml.WriteStartElement("category");
xml.WriteAttributeString("title", ce.Title);
ArrayList subCats = new ArrayList(ce.SubCategories);
subCats.Sort(new CategorySorter());
for (int i = 0; i < subCats.Count; ++i)
RecurseExport(xml, (CategoryEntry)subCats[i]);
ce.Matched.Sort(new CategorySorter());
for (int i = 0; i < ce.Matched.Count; ++i)
{
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
xml.WriteStartElement("object");
xml.WriteAttributeString("type", cte.Type.ToString());
object obj = cte.Object;
if (obj is Item)
{
Item item = (Item)obj;
int itemID = item.ItemID;
if (item is BaseAddon && ((BaseAddon)item).Components.Count == 1)
itemID = ((AddonComponent)(((BaseAddon)item).Components[0])).ItemID;
if (itemID > TileData.MaxItemValue)
itemID = 1;
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
int hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
item.Delete();
}
else if (obj is Mobile)
{
Mobile mob = (Mobile)obj;
int itemID = ShrinkTable.Lookup(mob, 1);
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
int hue = mob.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
mob.Delete();
}
xml.WriteEndElement();
}
xml.WriteEndElement();
}
public static void Load()
{
ArrayList types = new ArrayList();
AddTypes(Core.Assembly, types);
for (int i = 0; i < ScriptCompiler.Assemblies.Length; ++i)
AddTypes(ScriptCompiler.Assemblies[i], types);
m_RootItems = Load(types, "Data/items.cfg");
m_RootMobiles = Load(types, "Data/mobiles.cfg");
}
private static CategoryEntry Load(ArrayList types, string config)
{
CategoryLine[] lines = CategoryLine.Load(config);
if (lines.Length > 0)
{
int index = 0;
CategoryEntry root = new CategoryEntry(null, lines, ref index);
Fill(root, types);
return root;
}
return new CategoryEntry();
}
private static bool IsConstructable(Type type)
{
if (!type.IsSubclassOf(typeofItem) && !type.IsSubclassOf(typeofMobile))
return false;
ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
return (ctor != null && ctor.IsDefined(typeofConstructable, false));
}
private static void AddTypes(Assembly asm, ArrayList types)
{
Type[] allTypes = asm.GetTypes();
for (int i = 0; i < allTypes.Length; ++i)
{
Type type = allTypes[i];
if (type.IsAbstract)
continue;
if (IsConstructable(type))
types.Add(type);
}
}
private static void Fill(CategoryEntry root, ArrayList list)
{
for (int i = 0; i < list.Count; ++i)
{
Type type = (Type)list[i];
CategoryEntry match = GetDeepestMatch(root, type);
if (match == null)
continue;
try
{
match.Matched.Add(new CategoryTypeEntry(type));
}
catch
{
}
}
}
private static CategoryEntry GetDeepestMatch(CategoryEntry root, Type type)
{
if (!root.IsMatch(type))
return null;
for (int i = 0; i < root.SubCategories.Length; ++i)
{
CategoryEntry check = GetDeepestMatch(root.SubCategories[i], type);
if (check != null)
return check;
}
return root;
}
}
public class CategorySorter : IComparer
{
public int Compare(object x, object y)
{
string a = null, b = null;
if (x is CategoryEntry)
a = ((CategoryEntry)x).Title;
else if (x is CategoryTypeEntry)
a = ((CategoryTypeEntry)x).Type.Name;
if (y is CategoryEntry)
b = ((CategoryEntry)y).Title;
else if (y is CategoryTypeEntry)
b = ((CategoryTypeEntry)y).Type.Name;
if (a == null && b == null)
return 0;
if (a == null)
return 1;
if (b == null)
return -1;
return a.CompareTo(b);
}
}
public class CategoryTypeEntry
{
private readonly Type m_Type;
private readonly object m_Object;
public CategoryTypeEntry(Type type)
{
this.m_Type = type;
this.m_Object = Activator.CreateInstance(type);
}
public Type Type
{
get
{
return this.m_Type;
}
}
public object Object
{
get
{
return this.m_Object;
}
}
}
public class CategoryEntry
{
private readonly string m_Title;
private readonly Type[] m_Matches;
private readonly CategoryEntry[] m_SubCategories;
private readonly CategoryEntry m_Parent;
private readonly ArrayList m_Matched;
public CategoryEntry()
{
this.m_Title = "(empty)";
this.m_Matches = new Type[0];
this.m_SubCategories = new CategoryEntry[0];
this.m_Matched = new ArrayList();
}
public CategoryEntry(CategoryEntry parent, string title, CategoryEntry[] subCats)
{
this.m_Parent = parent;
this.m_Title = title;
this.m_SubCategories = subCats;
this.m_Matches = new Type[0];
this.m_Matched = new ArrayList();
}
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
{
this.m_Parent = parent;
string text = lines[index].Text;
int start = text.IndexOf('(');
if (start < 0)
throw new FormatException(String.Format("Input string not correctly formatted ('{0}')", text));
this.m_Title = text.Substring(0, start).Trim();
int end = text.IndexOf(')', ++start);
if (end < start)
throw new FormatException(String.Format("Input string not correctly formatted ('{0}')", text));
text = text.Substring(start, end - start);
string[] split = text.Split(';');
ArrayList list = new ArrayList();
for (int i = 0; i < split.Length; ++i)
{
Type type = ScriptCompiler.FindTypeByName(split[i].Trim());
if (type == null)
Console.WriteLine("Match type not found ('{0}')", split[i].Trim());
else
list.Add(type);
}
this.m_Matches = (Type[])list.ToArray(typeof(Type));
list.Clear();
int ourIndentation = lines[index].Indentation;
++index;
while (index < lines.Length && lines[index].Indentation > ourIndentation)
list.Add(new CategoryEntry(this, lines, ref index));
this.m_SubCategories = (CategoryEntry[])list.ToArray(typeof(CategoryEntry));
list.Clear();
this.m_Matched = list;
}
public string Title
{
get
{
return this.m_Title;
}
}
public Type[] Matches
{
get
{
return this.m_Matches;
}
}
public CategoryEntry Parent
{
get
{
return this.m_Parent;
}
}
public CategoryEntry[] SubCategories
{
get
{
return this.m_SubCategories;
}
}
public ArrayList Matched
{
get
{
return this.m_Matched;
}
}
public bool IsMatch(Type type)
{
bool isMatch = false;
for (int i = 0; !isMatch && i < this.m_Matches.Length; ++i)
isMatch = (type == this.m_Matches[i] || type.IsSubclassOf(this.m_Matches[i]));
return isMatch;
}
}
public class CategoryLine
{
private readonly int m_Indentation;
private readonly string m_Text;
public CategoryLine(string input)
{
int index;
for (index = 0; index < input.Length; ++index)
{
if (Char.IsLetter(input, index))
break;
}
if (index >= input.Length)
throw new FormatException(String.Format("Input string not correctly formatted ('{0}')", input));
this.m_Indentation = index;
this.m_Text = input.Substring(index);
}
public int Indentation
{
get
{
return this.m_Indentation;
}
}
public string Text
{
get
{
return this.m_Text;
}
}
public static CategoryLine[] Load(string path)
{
ArrayList list = new ArrayList();
if (File.Exists(path))
{
using (StreamReader ip = new StreamReader(path))
{
string line;
while ((line = ip.ReadLine()) != null)
list.Add(new CategoryLine(line));
}
}
return (CategoryLine[])list.ToArray(typeof(CategoryLine));
}
}
}

View File

@@ -0,0 +1,194 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using System.IO;
namespace Server.Commands
{
class Location : IComparable
{
public int X;
public int Y;
public int Z;
public Map Map;
public Location(int x, int y, int z, Map m)
{
X = x;
Y = y;
Z = z;
Map = m;
}
public int CompareTo(object obj)
{
if (!(obj is Location))
return GetHashCode().CompareTo(obj.GetHashCode());
Location l = (Location)obj;
if (l.Map.MapID != Map.MapID)
return l.Map.MapID - Map.MapID;
if (l.X != X)
return l.X - X;
if (l.Y != Y)
return l.Y - Y;
return l.Z - Z;
}
public override int GetHashCode()
{
string hashString = String.Format("{0}-{1}-{2}-{3}",
X, Y, Z, Map.MapID);
return hashString.GetHashCode();
}
}
class TelDef
{
public Location Source;
public Location Destination;
public bool Back;
public TelDef(Location s, Location d, bool b)
{
Source = s;
Destination = d;
Back = b;
}
}
public class GenTeleporter
{
private static string m_Path = Path.Combine("Data", "teleporters.csv");
private static char[] m_Sep = { ',' };
public GenTeleporter()
{
}
public static void Initialize()
{
CommandSystem.Register("TelGen", AccessLevel.Administrator, new CommandEventHandler(GenTeleporter_OnCommand));
CommandSystem.Register("TelGenDelete", AccessLevel.Administrator, new CommandEventHandler(TelGenDelete_OnCommand));
}
private static void TelGenDelete_OnCommand(CommandEventArgs e)
{
WeakEntityCollection.Delete("tel");
}
[Usage("TelGen")]
[Description("Generates world/dungeon teleporters for all facets.")]
public static void GenTeleporter_OnCommand(CommandEventArgs e)
{
e.Mobile.SendMessage("Generating teleporters, please wait.");
TeleportersCreator c = new TeleportersCreator();
StreamReader reader = new StreamReader(m_Path);
string line;
int lineNum = 0;
while((line = reader.ReadLine()) != null)
{
++lineNum;
line = line.Trim();
if (line.StartsWith("#"))
continue;
string[] parts = line.Split(m_Sep);
if(parts.Length != 9)
{
e.Mobile.SendMessage(33, String.Format("Bad teleporter definition on line {0}", lineNum));
continue;
}
try
{
c.CreateTeleporter(
int.Parse(parts[0]),
int.Parse(parts[1]),
int.Parse(parts[2]),
int.Parse(parts[4]),
int.Parse(parts[5]),
int.Parse(parts[6]),
Map.Parse(parts[3]),
Map.Parse(parts[7]),
bool.Parse(parts[8])
);
}
catch (FormatException)
{
e.Mobile.SendMessage(33, String.Format("Bad number format on line {0}", lineNum));
}
catch(ArgumentException ex)
{
e.Mobile.SendMessage(33, String.Format("Argument Execption {0} on line {1}", ex.Message, lineNum));
}
}
reader.Close();
e.Mobile.SendMessage("Teleporter generating complete.");
}
public class TeleportersCreator
{
private static readonly Queue m_Queue = new Queue();
private int m_Count;
public TeleportersCreator()
{
}
public static bool FindTeleporter(Map map, Point3D p)
{
IPooledEnumerable eable = map.GetItemsInRange(p, 0);
foreach (Item item in eable)
{
if (item is Teleporter && !(item is KeywordTeleporter) && !(item is SkillTeleporter))
{
int delta = item.Z - p.Z;
if (delta >= -12 && delta <= 12)
m_Queue.Enqueue(item);
}
}
eable.Free();
while (m_Queue.Count > 0)
((Item)m_Queue.Dequeue()).Delete();
return false;
}
public void CreateTeleporter(Point3D pointLocation, Point3D pointDestination, Map mapLocation, Map mapDestination, bool back)
{
if (!FindTeleporter(mapLocation, pointLocation))
{
this.m_Count++;
Teleporter tel = new Teleporter(pointDestination, mapDestination);
WeakEntityCollection.Add("tel", tel);
tel.MoveToWorld(pointLocation, mapLocation);
}
if (back && !FindTeleporter(mapDestination, pointDestination))
{
this.m_Count++;
Teleporter telBack = new Teleporter(pointLocation, mapLocation);
WeakEntityCollection.Add("tel", telBack);
telBack.MoveToWorld(pointDestination, mapDestination);
}
}
public void CreateTeleporter(int xLoc, int yLoc, int zLoc, int xDest, int yDest, int zDest, Map map, bool back)
{
this.CreateTeleporter(new Point3D(xLoc, yLoc, zLoc), new Point3D(xDest, yDest, zDest), map, map, back);
}
public void CreateTeleporter(int xLoc, int yLoc, int zLoc, int xDest, int yDest, int zDest, Map mapLocation, Map mapDestination, bool back)
{
this.CreateTeleporter(new Point3D(xLoc, yLoc, zLoc), new Point3D(xDest, yDest, zDest), mapLocation, mapDestination, back);
}
}
}
}

View File

@@ -0,0 +1,220 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.IO;
using System.Reflection;
namespace Server.Commands
{
public static class GenerateGameDocs
{
private static CsvFile csv;
private delegate void ProcessObject(object obj);
public static void Initialize()
{
CommandSystem.Register("GenGameDocs", AccessLevel.GameMaster, new CommandEventHandler(GenGameDocs_OnCommand));
}
private static void GenGameDocs_OnCommand(CommandEventArgs e)
{
csv = new CsvFile();
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == "Server.Mobiles" && typeof(Mobiles.BaseCreature).IsAssignableFrom(t))
.ToList()
.ForEach(t => ConsumeType(t, HandleBaseCreature));
csv.Write("Creatures.csv");
csv = new CsvFile();
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == "Server.Items" && typeof(Items.BaseWeapon).IsAssignableFrom(t))
.ToList()
.ForEach(t => ConsumeType(t, HandleBaseWeapon));
csv.Write("Weapons.csv");
csv = new CsvFile();
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == "Server.Items" && typeof(Items.BaseArmor).IsAssignableFrom(t))
.ToList()
.ForEach(t => ConsumeType(t, HandleBaseArmor));
csv.Write("Armor.csv");
}
private static void HandleBaseArmor(object obj)
{
Items.BaseArmor arm = obj as Items.BaseArmor;
if (arm == null)
return;
csv.AddRow();
csv.AddValue("Type", arm.GetType().Name);
csv.AddValue("Name", arm.Name);
csv.AddValue("Is Artifact?", arm.IsArtifact);
csv.AddValue("Pysical Resist", arm.PhysicalResistance);
csv.AddValue("Fire Resist", arm.FireResistance);
csv.AddValue("Cold Resist", arm.ColdResistance);
csv.AddValue("Poison Resist", arm.PoisonResistance);
csv.AddValue("Energy Resist", arm.EnergyResistance);
csv.AddValue("DCI", arm.Attributes.DefendChance);
}
private static void HandleBaseWeapon(object obj)
{
Items.BaseWeapon wep = obj as Items.BaseWeapon;
if (wep == null)
return;
csv.AddRow();
csv.AddValue("Type", wep.GetType().Name);
csv.AddValue("Name", wep.Name);
csv.AddValue("Is Artifact?", wep.IsArtifact);
csv.AddValue("Str Requirement", wep.StrRequirement);
csv.AddValue("Dex Requirement", wep.DexRequirement);
csv.AddValue("Int Requirement", wep.IntRequirement);
csv.AddValue("Skill", wep.Skill);
csv.AddValue("Race", wep.RequiredRace);
csv.AddValue("Speed", wep.MlSpeed);
csv.AddValue("Min Damage", wep.MinDamage);
csv.AddValue("Max Damage", wep.MaxDamage);
}
private static void HandleBaseCreature(object obj)
{
Mobiles.BaseCreature creature = obj as Mobiles.BaseCreature;
if (creature == null)
return;
Server.Items.BambooFlute flute = new Items.BambooFlute();
csv.AddRow();
csv.AddValue("Type", creature.GetType().Name);
csv.AddValue("Name", creature.Name);
csv.AddValue("Str", creature.Str);
csv.AddValue("Dex", creature.Dex);
csv.AddValue("Int", creature.Int);
csv.AddValue("Hits", creature.HitsMax);
csv.AddValue("Stam", creature.StamMax);
csv.AddValue("Mana", creature.ManaMax);
csv.AddValue("Physical Resist", creature.PhysicalResistance);
csv.AddValue("Fire Resist", creature.FireResistance);
csv.AddValue("Cold Resist", creature.ColdResistance);
csv.AddValue("Poison Resist", creature.PoisonResistance);
csv.AddValue("Energy Resist", creature.EnergyResistance);
csv.AddValue("Physical Damage", creature.PhysicalDamage);
csv.AddValue("Fire Damage", creature.FireDamage);
csv.AddValue("Cold Damage", creature.ColdDamage);
csv.AddValue("Poison Damage", creature.PoisonDamage);
csv.AddValue("Energy Damage", creature.EnergyDamage);
csv.AddValue("Taming Difficulty", creature.CurrentTameSkill);
csv.AddValue("Barding Difficulty", flute.GetDifficultyFor(creature));
csv.AddValue("TMap Level", creature.TreasureMapLevel);
csv.AddValue("Wrestling Skill", creature.Skills.Wrestling.Base);
}
private static void ConsumeType(Type t, ProcessObject proc)
{
ConstructorInfo ctor = t.GetConstructor(new Type[] { });
if (ctor == null)
return;
object obj;
try
{
obj = ctor.Invoke(new object[] { });
}
catch (Exception)
{
return;
}
if (obj == null)
return;
proc(obj);
}
private class CsvFile
{
private List<Dictionary<String, String>> rows = new List<Dictionary<string, string>>();
private Dictionary<String, String> currentRow = null;
private HashSet<String> headerSet = new HashSet<string>();
private List<String> allHeaders = new List<string>();
public CsvFile()
{
}
public void AddRow()
{
currentRow = new Dictionary<String, String>();
rows.Add(currentRow);
}
public void AddValue(String name, object value)
{
if (name == null)
return;
String v = "";
if (value != null)
v = value.ToString();
currentRow.Add(name, v.ToString());
if (headerSet.Contains(name))
return;
headerSet.Add(name);
allHeaders.Add(name);
}
public void Write(String path)
{
StreamWriter outf = new StreamWriter(path);
bool first;
first = true;
foreach(String header in allHeaders)
{
if (first)
{
outf.Write(String.Format("\"{0}\"", header));
first = false;
}
else
{
outf.Write(String.Format(",\"{0}\"", header));
}
}
outf.WriteLine("");
foreach(Dictionary<String, String> row in rows)
{
first = true;
foreach (String header in allHeaders)
{
String value = "";
row.TryGetValue(header, out value);
if (first)
{
outf.Write(String.Format("\"{0}\"", value));
first = false;
}
else
{
outf.Write(String.Format(",\"{0}\"", value));
}
}
outf.WriteLine("");
}
outf.Close();
}
}
}
}

View File

@@ -0,0 +1,237 @@
using System;
using System.Collections;
using Server.Gumps;
namespace Server.Commands.Generic
{
public enum ObjectTypes
{
Both,
Items,
Mobiles,
All
}
public abstract class BaseCommand
{
private readonly ArrayList m_Responses;
private readonly ArrayList m_Failures;
private string[] m_Commands;
private AccessLevel m_AccessLevel;
private CommandSupport m_Implementors;
private ObjectTypes m_ObjectTypes;
private bool m_ListOptimized;
private string m_Usage;
private string m_Description;
public BaseCommand()
{
this.m_Responses = new ArrayList();
this.m_Failures = new ArrayList();
}
public bool ListOptimized
{
get
{
return this.m_ListOptimized;
}
set
{
this.m_ListOptimized = value;
}
}
public string[] Commands
{
get
{
return this.m_Commands;
}
set
{
this.m_Commands = value;
}
}
public string Usage
{
get
{
return this.m_Usage;
}
set
{
this.m_Usage = value;
}
}
public string Description
{
get
{
return this.m_Description;
}
set
{
this.m_Description = value;
}
}
public AccessLevel AccessLevel
{
get
{
return this.m_AccessLevel;
}
set
{
this.m_AccessLevel = value;
}
}
public ObjectTypes ObjectTypes
{
get
{
return this.m_ObjectTypes;
}
set
{
this.m_ObjectTypes = value;
}
}
public CommandSupport Supports
{
get
{
return this.m_Implementors;
}
set
{
this.m_Implementors = value;
}
}
public static bool IsAccessible(Mobile from, object obj)
{
if (from.AccessLevel >= AccessLevel.Administrator || obj == null)
return true;
Mobile mob;
if (obj is Mobile)
mob = (Mobile)obj;
else if (obj is Item)
mob = ((Item)obj).RootParent as Mobile;
else
mob = null;
if (mob == null || mob == from || from.AccessLevel > mob.AccessLevel)
return true;
return false;
}
public virtual void ExecuteList(CommandEventArgs e, ArrayList list)
{
for (int i = 0; i < list.Count; ++i)
this.Execute(e, list[i]);
}
public virtual void Execute(CommandEventArgs e, object obj)
{
}
public virtual bool ValidateArgs(BaseCommandImplementor impl, CommandEventArgs e)
{
return true;
}
public void AddResponse(string message)
{
for (int i = 0; i < this.m_Responses.Count; ++i)
{
MessageEntry entry = (MessageEntry)this.m_Responses[i];
if (entry.m_Message == message)
{
++entry.m_Count;
return;
}
}
if (this.m_Responses.Count == 10)
return;
this.m_Responses.Add(new MessageEntry(message));
}
public void AddResponse(Gump gump)
{
this.m_Responses.Add(gump);
}
public void LogFailure(string message)
{
for (int i = 0; i < this.m_Failures.Count; ++i)
{
MessageEntry entry = (MessageEntry)this.m_Failures[i];
if (entry.m_Message == message)
{
++entry.m_Count;
return;
}
}
if (this.m_Failures.Count == 10)
return;
this.m_Failures.Add(new MessageEntry(message));
}
public void Flush(Mobile from, bool flushToLog)
{
if (this.m_Responses.Count > 0)
{
for (int i = 0; i < this.m_Responses.Count; ++i)
{
object obj = this.m_Responses[i];
if (obj is MessageEntry)
{
from.SendMessage(((MessageEntry)obj).ToString());
if (flushToLog)
CommandLogging.WriteLine(from, ((MessageEntry)obj).ToString());
}
else if (obj is Gump)
{
from.SendGump((Gump)obj);
}
}
}
else
{
for (int i = 0; i < this.m_Failures.Count; ++i)
from.SendMessage(((MessageEntry)this.m_Failures[i]).ToString());
}
this.m_Responses.Clear();
this.m_Failures.Clear();
}
private class MessageEntry
{
public readonly string m_Message;
public int m_Count;
public MessageEntry(string message)
{
this.m_Message = message;
this.m_Count = 1;
}
public override string ToString()
{
if (this.m_Count > 1)
return String.Format("{0} ({1})", this.m_Message, this.m_Count);
return this.m_Message;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
using Server.Items;
using Server.Multis;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class DesignInsertCommand : BaseCommand
{
public static void Initialize()
{
TargetCommands.Register(new DesignInsertCommand());
}
public DesignInsertCommand()
{
this.AccessLevel = AccessLevel.GameMaster;
this.Supports = CommandSupport.Single | CommandSupport.Area;
this.Commands = new string[] { "DesignInsert" };
this.ObjectTypes = ObjectTypes.Items;
this.Usage = "DesignInsert [allItems=false]";
this.Description = "Inserts multiple targeted items into a customizable house's design.";
}
#region Single targeting mode
public override void Execute(CommandEventArgs e, object obj)
{
Target t = new DesignInsertTarget(new List<HouseFoundation>(), (e.Length < 1 || !e.GetBoolean(0)));
t.Invoke(e.Mobile, obj);
}
private class DesignInsertTarget : Target
{
private readonly List<HouseFoundation> m_Foundations;
private readonly bool m_StaticsOnly;
public DesignInsertTarget(List<HouseFoundation> foundations, bool staticsOnly)
: base(-1, false, TargetFlags.None)
{
this.m_Foundations = foundations;
this.m_StaticsOnly = staticsOnly;
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (this.m_Foundations.Count != 0)
{
from.SendMessage("Your changes have been committed. Updating...");
foreach (HouseFoundation house in this.m_Foundations)
house.Delta(ItemDelta.Update);
}
}
protected override void OnTarget(Mobile from, object obj)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(obj as Item, this.m_StaticsOnly, out house);
switch ( result )
{
case DesignInsertResult.Valid:
{
if (this.m_Foundations.Count == 0)
from.SendMessage("The item has been inserted into the house design. Press ESC when you are finished.");
else
from.SendMessage("The item has been inserted into the house design.");
if (!this.m_Foundations.Contains(house))
this.m_Foundations.Add(house);
break;
}
case DesignInsertResult.InvalidItem:
{
from.SendMessage("That cannot be inserted. Try again.");
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
from.SendMessage("That item is not inside a customizable house. Try again.");
break;
}
}
from.Target = new DesignInsertTarget(this.m_Foundations, this.m_StaticsOnly);
}
}
#endregion
#region Area targeting mode
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
e.Mobile.SendGump(new WarningGump(1060637, 30720, String.Format("You are about to insert {0} objects. This cannot be undone without a full server revert.<br><br>Continue?", list.Count), 0xFFC000, 420, 280, new WarningGumpCallback(OnConfirmCallback), new object[] { e, list, (e.Length < 1 || !e.GetBoolean(0)) }));
this.AddResponse("Awaiting confirmation...");
}
private void OnConfirmCallback(Mobile from, bool okay, object state)
{
object[] states = (object[])state;
CommandEventArgs e = (CommandEventArgs)states[0];
ArrayList list = (ArrayList)states[1];
bool staticsOnly = (bool)states[2];
bool flushToLog = false;
if (okay)
{
List<HouseFoundation> foundations = new List<HouseFoundation>();
flushToLog = (list.Count > 20);
for (int i = 0; i < list.Count; ++i)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
switch ( result )
{
case DesignInsertResult.Valid:
{
this.AddResponse("The item has been inserted into the house design.");
if (!foundations.Contains(house))
foundations.Add(house);
break;
}
case DesignInsertResult.InvalidItem:
{
this.LogFailure("That cannot be inserted.");
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
this.LogFailure("That item is not inside a customizable house.");
break;
}
}
}
foreach (HouseFoundation house in foundations)
house.Delta(ItemDelta.Update);
}
else
{
this.AddResponse("Command aborted.");
}
this.Flush(from, flushToLog);
}
#endregion
public enum DesignInsertResult
{
Valid,
InvalidItem,
NotInHouse,
OutsideHouseBounds
}
public static DesignInsertResult ProcessInsert(Item item, bool staticsOnly, out HouseFoundation house)
{
house = null;
if (item == null || item is BaseMulti || item is HouseSign || (staticsOnly && !(item is Static)))
return DesignInsertResult.InvalidItem;
house = BaseHouse.FindHouseAt(item) as HouseFoundation;
if (house == null)
return DesignInsertResult.NotInHouse;
int x = item.X - house.X;
int y = item.Y - house.Y;
int z = item.Z - house.Z;
if (!TryInsertIntoState(house.CurrentState, item.ItemID, x, y, z))
return DesignInsertResult.OutsideHouseBounds;
TryInsertIntoState(house.DesignState, item.ItemID, x, y, z);
item.Delete();
return DesignInsertResult.Valid;
}
private static bool TryInsertIntoState(DesignState state, int itemID, int x, int y, int z)
{
MultiComponentList mcl = state.Components;
if (x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y)
return false;
mcl.Add(itemID, x, y, z);
state.OnRevised();
return true;
}
}
}

View File

@@ -0,0 +1,557 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Server.Gumps;
using Server.Network;
using Server.Targets;
namespace Server.Commands.Generic
{
public class InterfaceCommand : BaseCommand
{
public InterfaceCommand()
{
this.AccessLevel = AccessLevel.GameMaster;
this.Supports = CommandSupport.Complex | CommandSupport.Simple;
this.Commands = new string[] { "Interface" };
this.ObjectTypes = ObjectTypes.Both;
this.Usage = "Interface [view <properties ...>]";
this.Description = "Opens an interface to interact with matched objects. Generally used with condition arguments.";
this.ListOptimized = true;
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
if (list.Count > 0)
{
List<string> columns = new List<string>();
columns.Add("Object");
if (e.Length > 0)
{
int offset = 0;
if (Insensitive.Equals(e.GetString(0), "view"))
++offset;
while (offset < e.Length)
columns.Add(e.GetString(offset++));
}
e.Mobile.SendGump(new InterfaceGump(e.Mobile, columns.ToArray(), list, 0, null));
}
else
{
this.AddResponse("No matching objects found.");
}
}
}
public class InterfaceGump : BaseGridGump
{
private const int EntriesPerPage = 15;
private readonly Mobile m_From;
private readonly string[] m_Columns;
private readonly ArrayList m_List;
private readonly int m_Page;
private readonly object m_Select;
public InterfaceGump(Mobile from, string[] columns, ArrayList list, int page, object select)
: base(30, 30)
{
this.m_From = from;
this.m_Columns = columns;
this.m_List = list;
this.m_Page = page;
this.m_Select = select;
this.Render();
}
public void Render()
{
this.AddNewPage();
if (this.m_Page > 0)
this.AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
else
this.AddEntryHeader(20);
this.AddEntryHtml(40 + (this.m_Columns.Length * 130) - 20 + ((this.m_Columns.Length - 2) * this.OffsetSize), this.Center(String.Format("Page {0} of {1}", this.m_Page + 1, (this.m_List.Count + EntriesPerPage - 1) / EntriesPerPage)));
if ((this.m_Page + 1) * EntriesPerPage < this.m_List.Count)
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight);
else
this.AddEntryHeader(20);
if (this.m_Columns.Length > 1)
{
this.AddNewLine();
for (int i = 0; i < this.m_Columns.Length; ++i)
{
if (i > 0 && this.m_List.Count > 0)
{
object obj = this.m_List[0];
if (obj != null)
{
string failReason = null;
PropertyInfo[] chain = Properties.GetPropertyInfoChain(this.m_From, obj.GetType(), this.m_Columns[i], PropertyAccess.Read, ref failReason);
if (chain != null && chain.Length > 0)
{
this.m_Columns[i] = "";
for (int j = 0; j < chain.Length; ++j)
{
if (j > 0)
this.m_Columns[i] += '.';
this.m_Columns[i] += chain[j].Name;
}
}
}
}
this.AddEntryHtml(130 + (i == 0 ? 40 : 0), this.m_Columns[i]);
}
this.AddEntryHeader(20);
}
for (int i = this.m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < this.m_List.Count; ++i, ++line)
{
this.AddNewLine();
object obj = this.m_List[i];
bool isDeleted = false;
if (obj is Item)
{
Item item = (Item)obj;
if (!(isDeleted = item.Deleted))
this.AddEntryHtml(40 + 130, item.GetType().Name);
}
else if (obj is Mobile)
{
Mobile mob = (Mobile)obj;
if (!(isDeleted = mob.Deleted))
this.AddEntryHtml(40 + 130, mob.Name);
}
if (isDeleted)
{
this.AddEntryHtml(40 + 130, "(deleted)");
for (int j = 1; j < this.m_Columns.Length; ++j)
this.AddEntryHtml(130, "---");
this.AddEntryHeader(20);
}
else
{
for (int j = 1; j < this.m_Columns.Length; ++j)
{
object src = obj;
string value;
string failReason = "";
PropertyInfo[] chain = Properties.GetPropertyInfoChain(this.m_From, src.GetType(), this.m_Columns[j], PropertyAccess.Read, ref failReason);
if (chain == null || chain.Length == 0)
{
value = "---";
}
else
{
PropertyInfo p = Properties.GetPropertyInfo(ref src, chain, ref failReason);
if (p == null)
value = "---";
else
value = PropertiesGump.ValueToString(src, p);
}
this.AddEntryHtml(130, value);
}
bool isSelected = (this.m_Select != null && obj == this.m_Select);
this.AddEntryButton(20, (isSelected ? 9762 : ArrowRightID1), (isSelected ? 9763 : ArrowRightID2), 3 + i, ArrowRightWidth, ArrowRightHeight);
}
}
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
switch ( info.ButtonID )
{
case 1:
{
if (this.m_Page > 0)
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page - 1, this.m_Select));
break;
}
case 2:
{
if ((this.m_Page + 1) * EntriesPerPage < this.m_List.Count)
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page + 1, this.m_Select));
break;
}
default:
{
int v = info.ButtonID - 3;
if (v >= 0 && v < this.m_List.Count)
{
object obj = this.m_List[v];
if (!BaseCommand.IsAccessible(this.m_From, obj))
{
this.m_From.SendMessage("That is not accessible.");
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Select));
break;
}
if (obj is Item && !((Item)obj).Deleted)
this.m_From.SendGump(new InterfaceItemGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, (Item)obj));
else if (obj is Mobile && !((Mobile)obj).Deleted)
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, (Mobile)obj));
else
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Select));
}
break;
}
}
}
}
public class InterfaceItemGump : BaseGridGump
{
private readonly Mobile m_From;
private readonly string[] m_Columns;
private readonly ArrayList m_List;
private readonly int m_Page;
private readonly Item m_Item;
public InterfaceItemGump(Mobile from, string[] columns, ArrayList list, int page, Item item)
: base(30, 30)
{
this.m_From = from;
this.m_Columns = columns;
this.m_List = list;
this.m_Page = page;
this.m_Item = item;
this.Render();
}
public void Render()
{
this.AddNewPage();
this.AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
this.AddEntryHtml(160, this.m_Item.GetType().Name);
this.AddEntryHeader(20);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Properties");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Delete");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3, ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Go there");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 4, ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Move to target");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 5, ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Bring to pack");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 6, ArrowRightWidth, ArrowRightHeight);
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (this.m_Item.Deleted)
{
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
return;
}
else if (!BaseCommand.IsAccessible(this.m_From, this.m_Item))
{
this.m_From.SendMessage("That is no longer accessible.");
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
return;
}
switch ( info.ButtonID )
{
case 0:
case 1:
{
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
break;
}
case 2: // Properties
{
this.m_From.SendGump(new InterfaceItemGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
this.m_From.SendGump(new PropertiesGump(this.m_From, this.m_Item));
break;
}
case 3: // Delete
{
CommandLogging.WriteLine(this.m_From, "{0} {1} deleting {2}", this.m_From.AccessLevel, CommandLogging.Format(this.m_From), CommandLogging.Format(this.m_Item));
this.m_Item.Delete();
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
break;
}
case 4: // Go there
{
this.m_From.SendGump(new InterfaceItemGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
this.InvokeCommand(String.Format("Go {0}", this.m_Item.Serial.Value));
break;
}
case 5: // Move to target
{
this.m_From.SendGump(new InterfaceItemGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
this.m_From.Target = new MoveTarget(this.m_Item);
break;
}
case 6: // Bring to pack
{
Mobile owner = this.m_Item.RootParent as Mobile;
if (owner != null && (owner.Map != null && owner.Map != Map.Internal) && !BaseCommand.IsAccessible(this.m_From, owner) /* !m_From.CanSee( owner )*/)
{
this.m_From.SendMessage("You can not get what you can not see.");
}
else if (owner != null && (owner.Map == null || owner.Map == Map.Internal) && owner.Hidden && owner.AccessLevel >= this.m_From.AccessLevel)
{
this.m_From.SendMessage("You can not get what you can not see.");
}
else
{
this.m_From.SendGump(new InterfaceItemGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Item));
this.m_From.AddToBackpack(this.m_Item);
}
break;
}
}
}
private void InvokeCommand(string ip)
{
CommandSystem.Handle(this.m_From, String.Format("{0}{1}", CommandSystem.Prefix, ip));
}
}
public class InterfaceMobileGump : BaseGridGump
{
private readonly Mobile m_From;
private readonly string[] m_Columns;
private readonly ArrayList m_List;
private readonly int m_Page;
private readonly Mobile m_Mobile;
public InterfaceMobileGump(Mobile from, string[] columns, ArrayList list, int page, Mobile mob)
: base(30, 30)
{
this.m_From = from;
this.m_Columns = columns;
this.m_List = list;
this.m_Page = page;
this.m_Mobile = mob;
this.Render();
}
public void Render()
{
this.AddNewPage();
this.AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
this.AddEntryHtml(160, this.m_Mobile.Name);
this.AddEntryHeader(20);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Properties");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight);
if (!this.m_Mobile.Player)
{
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Delete");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3, ArrowRightWidth, ArrowRightHeight);
}
if (this.m_Mobile != this.m_From)
{
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Go to there");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 4, ArrowRightWidth, ArrowRightHeight);
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Bring them here");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 5, ArrowRightWidth, ArrowRightHeight);
}
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Move to target");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 6, ArrowRightWidth, ArrowRightHeight);
if (this.m_From == this.m_Mobile || this.m_From.AccessLevel > this.m_Mobile.AccessLevel)
{
this.AddNewLine();
if (this.m_Mobile.Alive)
{
this.AddEntryHtml(20 + this.OffsetSize + 160, "Kill");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 7, ArrowRightWidth, ArrowRightHeight);
}
else
{
this.AddEntryHtml(20 + this.OffsetSize + 160, "Resurrect");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 8, ArrowRightWidth, ArrowRightHeight);
}
}
if (this.m_Mobile.NetState != null)
{
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, "Client");
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 9, ArrowRightWidth, ArrowRightHeight);
}
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (this.m_Mobile.Deleted)
{
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
return;
}
else if (!BaseCommand.IsAccessible(this.m_From, this.m_Mobile))
{
this.m_From.SendMessage("That is no longer accessible.");
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
return;
}
switch ( info.ButtonID )
{
case 0:
case 1:
{
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
break;
}
case 2: // Properties
{
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
this.m_From.SendGump(new PropertiesGump(this.m_From, this.m_Mobile));
break;
}
case 3: // Delete
{
if (!this.m_Mobile.Player)
{
CommandLogging.WriteLine(this.m_From, "{0} {1} deleting {2}", this.m_From.AccessLevel, CommandLogging.Format(this.m_From), CommandLogging.Format(this.m_Mobile));
this.m_Mobile.Delete();
this.m_From.SendGump(new InterfaceGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
}
break;
}
case 4: // Go there
{
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
this.InvokeCommand(String.Format("Go {0}", this.m_Mobile.Serial.Value));
break;
}
case 5: // Bring them here
{
if (this.m_From.Map == null || this.m_From.Map == Map.Internal)
{
this.m_From.SendMessage("You cannot bring that person here.");
}
else
{
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
this.m_Mobile.MoveToWorld(this.m_From.Location, this.m_From.Map);
}
break;
}
case 6: // Move to target
{
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
this.m_From.Target = new MoveTarget(this.m_Mobile);
break;
}
case 7: // Kill
{
if (this.m_From == this.m_Mobile || this.m_From.AccessLevel > this.m_Mobile.AccessLevel)
this.m_Mobile.Kill();
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
break;
}
case 8: // Res
{
if (this.m_From == this.m_Mobile || this.m_From.AccessLevel > this.m_Mobile.AccessLevel)
{
this.m_Mobile.PlaySound(0x214);
this.m_Mobile.FixedEffect(0x376A, 10, 16);
this.m_Mobile.Resurrect();
}
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
break;
}
case 9: // Client
{
this.m_From.SendGump(new InterfaceMobileGump(this.m_From, this.m_Columns, this.m_List, this.m_Page, this.m_Mobile));
if (this.m_Mobile.NetState != null)
this.m_From.SendGump(new ClientGump(this.m_From, this.m_Mobile.NetState));
break;
}
}
}
private void InvokeCommand(string ip)
{
CommandSystem.Handle(this.m_From, String.Format("{0}{1}", CommandSystem.Prefix, ip));
}
}
}

View File

@@ -0,0 +1,198 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
public delegate BaseExtension ExtensionConstructor();
public sealed class ExtensionInfo
{
private static readonly Dictionary<string, ExtensionInfo> m_Table = new Dictionary<string, ExtensionInfo>(StringComparer.InvariantCultureIgnoreCase);
private readonly int m_Order;
private readonly string m_Name;
private readonly int m_Size;
private readonly ExtensionConstructor m_Constructor;
public ExtensionInfo(int order, string name, int size, ExtensionConstructor constructor)
{
this.m_Name = name;
this.m_Size = size;
this.m_Order = order;
this.m_Constructor = constructor;
}
public static Dictionary<string, ExtensionInfo> Table
{
get
{
return m_Table;
}
}
public int Order
{
get
{
return this.m_Order;
}
}
public string Name
{
get
{
return this.m_Name;
}
}
public int Size
{
get
{
return this.m_Size;
}
}
public bool IsFixedSize
{
get
{
return (this.m_Size >= 0);
}
}
public ExtensionConstructor Constructor
{
get
{
return this.m_Constructor;
}
}
public static void Register(ExtensionInfo ext)
{
m_Table[ext.m_Name] = ext;
}
}
public sealed class Extensions : List<BaseExtension>
{
public Extensions()
{
}
public static Extensions Parse(Mobile from, ref string[] args)
{
Extensions parsed = new Extensions();
int size = args.Length;
Type baseType = null;
for (int i = args.Length - 1; i >= 0; --i)
{
ExtensionInfo extInfo = null;
if (!ExtensionInfo.Table.TryGetValue(args[i], out extInfo))
continue;
if (extInfo.IsFixedSize && i != (size - extInfo.Size - 1))
throw new Exception("Invalid extended argument count.");
BaseExtension ext = extInfo.Constructor();
ext.Parse(from, args, i + 1, size - i - 1);
if (ext is WhereExtension)
baseType = (ext as WhereExtension).Conditional.Type;
parsed.Add(ext);
size = i;
}
parsed.Sort(delegate(BaseExtension a, BaseExtension b)
{
return (a.Order - b.Order);
});
AssemblyEmitter emitter = null;
foreach (BaseExtension update in parsed)
update.Optimize(from, baseType, ref emitter);
if (size != args.Length)
{
string[] old = args;
args = new string[size];
for (int i = 0; i < args.Length; ++i)
args[i] = old[i];
}
return parsed;
}
public bool IsValid(object obj)
{
for (int i = 0; i < this.Count; ++i)
{
if (!this[i].IsValid(obj))
return false;
}
return true;
}
public void Filter(ArrayList list)
{
for (int i = 0; i < this.Count; ++i)
this[i].Filter(list);
}
}
public abstract class BaseExtension
{
public abstract ExtensionInfo Info { get; }
public string Name
{
get
{
return this.Info.Name;
}
}
public int Size
{
get
{
return this.Info.Size;
}
}
public bool IsFixedSize
{
get
{
return this.Info.IsFixedSize;
}
}
public int Order
{
get
{
return this.Info.Order;
}
}
public virtual void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
}
public virtual void Parse(Mobile from, string[] arguments, int offset, int size)
{
}
public virtual bool IsValid(object obj)
{
return true;
}
public virtual void Filter(ArrayList list)
{
}
}
}

View File

@@ -0,0 +1,549 @@
using System;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
namespace Server.Commands.Generic
{
public interface IConditional
{
bool Verify(object obj);
}
public interface ICondition
{
// Invoked during the constructor
void Construct(TypeBuilder typeBuilder, ILGenerator il, int index);
// Target object will be loaded on the stack
void Compile(MethodEmitter emitter);
}
public sealed class TypeCondition : ICondition
{
public static TypeCondition Default = new TypeCondition();
void ICondition.Construct(TypeBuilder typeBuilder, ILGenerator il, int index)
{
}
void ICondition.Compile(MethodEmitter emitter)
{
// The object was safely cast to be the conditionals type
// If it's null, then the type cast didn't work...
emitter.LoadNull();
emitter.Compare(OpCodes.Ceq);
emitter.LogicalNot();
}
}
public sealed class PropertyValue
{
private readonly Type m_Type;
private object m_Value;
private FieldInfo m_Field;
public Type Type
{
get
{
return this.m_Type;
}
}
public object Value
{
get
{
return this.m_Value;
}
}
public FieldInfo Field
{
get
{
return this.m_Field;
}
}
public bool HasField
{
get
{
return (this.m_Field != null);
}
}
public PropertyValue(Type type, object value)
{
this.m_Type = type;
this.m_Value = value;
}
public void Load(MethodEmitter method)
{
if (this.m_Field != null)
{
method.LoadArgument(0);
method.LoadField(this.m_Field);
}
else if (this.m_Value == null)
{
method.LoadNull(this.m_Type);
}
else
{
if (this.m_Value is int)
method.Load((int)this.m_Value);
else if (this.m_Value is long)
method.Load((long)this.m_Value);
else if (this.m_Value is float)
method.Load((float)this.m_Value);
else if (this.m_Value is double)
method.Load((double)this.m_Value);
else if (this.m_Value is char)
method.Load((char)this.m_Value);
else if (this.m_Value is bool)
method.Load((bool)this.m_Value);
else if (this.m_Value is string)
method.Load((string)this.m_Value);
else if (this.m_Value is Enum)
method.Load((Enum)this.m_Value);
else
throw new InvalidOperationException("Unrecognized comparison value.");
}
}
public void Acquire(TypeBuilder typeBuilder, ILGenerator il, string fieldName)
{
if (this.m_Value is string)
{
string toParse = (string)this.m_Value;
if (!this.m_Type.IsValueType && toParse == "null")
{
this.m_Value = null;
}
else if (this.m_Type == typeof(string))
{
if (toParse == @"@""null""")
toParse = "null";
this.m_Value = toParse;
}
else if (this.m_Type.IsEnum)
{
this.m_Value = Enum.Parse(this.m_Type, toParse, true);
}
else
{
MethodInfo parseMethod = null;
object[] parseArgs = null;
MethodInfo parseNumber = this.m_Type.GetMethod(
"Parse",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { typeof(string), typeof(NumberStyles) },
null);
if (parseNumber != null)
{
NumberStyles style = NumberStyles.Integer;
if (Insensitive.StartsWith(toParse, "0x"))
{
style = NumberStyles.HexNumber;
toParse = toParse.Substring(2);
}
parseMethod = parseNumber;
parseArgs = new object[] { toParse, style };
}
else
{
MethodInfo parseGeneral = this.m_Type.GetMethod(
"Parse",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { typeof(string) },
null);
parseMethod = parseGeneral;
parseArgs = new object[] { toParse };
}
if (parseMethod != null)
{
this.m_Value = parseMethod.Invoke(null, parseArgs);
if (!this.m_Type.IsPrimitive)
{
this.m_Field = typeBuilder.DefineField(
fieldName,
this.m_Type,
FieldAttributes.Private | FieldAttributes.InitOnly);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, toParse);
if (parseArgs.Length == 2) // dirty evil hack :-(
il.Emit(OpCodes.Ldc_I4, (int)parseArgs[1]);
il.Emit(OpCodes.Call, parseMethod);
il.Emit(OpCodes.Stfld, this.m_Field);
}
}
else
{
throw new InvalidOperationException(
String.Format(
"Unable to convert string \"{0}\" into type '{1}'.",
this.m_Value,
this.m_Type));
}
}
}
}
}
public abstract class PropertyCondition : ICondition
{
protected Property m_Property;
protected bool m_Not;
public PropertyCondition(Property property, bool not)
{
this.m_Property = property;
this.m_Not = not;
}
public abstract void Construct(TypeBuilder typeBuilder, ILGenerator il, int index);
public abstract void Compile(MethodEmitter emitter);
}
public enum StringOperator
{
Equal,
NotEqual,
Contains,
StartsWith,
EndsWith
}
public sealed class StringCondition : PropertyCondition
{
private readonly StringOperator m_Operator;
private readonly PropertyValue m_Value;
private readonly bool m_IgnoreCase;
public StringCondition(Property property, bool not, StringOperator op, object value, bool ignoreCase)
: base(property, not)
{
this.m_Operator = op;
this.m_Value = new PropertyValue(property.Type, value);
this.m_IgnoreCase = ignoreCase;
}
public override void Construct(TypeBuilder typeBuilder, ILGenerator il, int index)
{
this.m_Value.Acquire(typeBuilder, il, "v" + index);
}
public override void Compile(MethodEmitter emitter)
{
bool inverse = false;
string methodName;
switch ( this.m_Operator )
{
case StringOperator.Equal:
methodName = "Equals";
break;
case StringOperator.NotEqual:
methodName = "Equals";
inverse = true;
break;
case StringOperator.Contains:
methodName = "Contains";
break;
case StringOperator.StartsWith:
methodName = "StartsWith";
break;
case StringOperator.EndsWith:
methodName = "EndsWith";
break;
default:
throw new InvalidOperationException("Invalid string comparison operator.");
}
if (this.m_IgnoreCase || methodName == "Equals")
{
Type type = (this.m_IgnoreCase ? typeof(Insensitive) : typeof(String));
emitter.BeginCall(
type.GetMethod(
methodName,
BindingFlags.Public | BindingFlags.Static,
null,
new Type[]
{
typeof(string),
typeof(string)
},
null));
emitter.Chain(this.m_Property);
this.m_Value.Load(emitter);
emitter.FinishCall();
}
else
{
Label notNull = emitter.CreateLabel();
Label moveOn = emitter.CreateLabel();
LocalBuilder temp = emitter.AcquireTemp(this.m_Property.Type);
emitter.Chain(this.m_Property);
emitter.StoreLocal(temp);
emitter.LoadLocal(temp);
emitter.BranchIfTrue(notNull);
emitter.Load(false);
emitter.Pop();
emitter.Branch(moveOn);
emitter.MarkLabel(notNull);
emitter.LoadLocal(temp);
emitter.BeginCall(
typeof(string).GetMethod(
methodName,
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[]
{
typeof(string)
},
null));
this.m_Value.Load(emitter);
emitter.FinishCall();
emitter.MarkLabel(moveOn);
}
if (this.m_Not != inverse)
emitter.LogicalNot();
}
}
public enum ComparisonOperator
{
Equal,
NotEqual,
Greater,
GreaterEqual,
Lesser,
LesserEqual
}
public sealed class ComparisonCondition : PropertyCondition
{
private readonly ComparisonOperator m_Operator;
private readonly PropertyValue m_Value;
public ComparisonCondition(Property property, bool not, ComparisonOperator op, object value)
: base(property, not)
{
this.m_Operator = op;
this.m_Value = new PropertyValue(property.Type, value);
}
public override void Construct(TypeBuilder typeBuilder, ILGenerator il, int index)
{
this.m_Value.Acquire(typeBuilder, il, "v" + index);
}
public override void Compile(MethodEmitter emitter)
{
emitter.Chain(this.m_Property);
bool inverse = false;
bool couldCompare =
emitter.CompareTo(1, delegate()
{
this.m_Value.Load(emitter);
});
if (couldCompare)
{
emitter.Load(0);
switch ( this.m_Operator )
{
case ComparisonOperator.Equal:
emitter.Compare(OpCodes.Ceq);
break;
case ComparisonOperator.NotEqual:
emitter.Compare(OpCodes.Ceq);
inverse = true;
break;
case ComparisonOperator.Greater:
emitter.Compare(OpCodes.Cgt);
break;
case ComparisonOperator.GreaterEqual:
emitter.Compare(OpCodes.Clt);
inverse = true;
break;
case ComparisonOperator.Lesser:
emitter.Compare(OpCodes.Clt);
break;
case ComparisonOperator.LesserEqual:
emitter.Compare(OpCodes.Cgt);
inverse = true;
break;
default:
throw new InvalidOperationException("Invalid comparison operator.");
}
}
else
{
// This type is -not- comparable
// We can only support == and != operations
this.m_Value.Load(emitter);
switch ( this.m_Operator )
{
case ComparisonOperator.Equal:
emitter.Compare(OpCodes.Ceq);
break;
case ComparisonOperator.NotEqual:
emitter.Compare(OpCodes.Ceq);
inverse = true;
break;
case ComparisonOperator.Greater:
case ComparisonOperator.GreaterEqual:
case ComparisonOperator.Lesser:
case ComparisonOperator.LesserEqual:
throw new InvalidOperationException("Property does not support relational comparisons.");
default:
throw new InvalidOperationException("Invalid operator.");
}
}
if (this.m_Not != inverse)
emitter.LogicalNot();
}
}
public static class ConditionalCompiler
{
public static IConditional Compile(AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__conditional" + index,
TypeAttributes.Public,
typeof(object));
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
for (int i = 0; i < conditions.Length; ++i)
conditions[i].Construct(typeBuilder, il, i);
// return;
il.Emit(OpCodes.Ret);
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation(typeof(IConditional));
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "Verify",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(bool),
/* params */ new Type[] { typeof(object) });
LocalBuilder obj = emitter.CreateLocal(objectType);
LocalBuilder eq = emitter.CreateLocal(typeof(bool));
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(obj);
Label done = emitter.CreateLabel();
for (int i = 0; i < conditions.Length; ++i)
{
if (i > 0)
{
emitter.LoadLocal(eq);
emitter.BranchIfFalse(done);
}
emitter.LoadLocal(obj);
conditions[i].Compile(emitter);
emitter.StoreLocal(eq);
}
emitter.MarkLabel(done);
emitter.LoadLocal(eq);
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IConditional).GetMethod(
"Verify",
new Type[]
{
typeof(object)
}));
compareMethod = emitter.Method;
}
#endregion
#endregion
Type conditionalType = typeBuilder.CreateType();
return (IConditional)Activator.CreateInstance(conditionalType);
}
}
}

View File

@@ -0,0 +1,239 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
namespace Server.Commands.Generic
{
public static class DistinctCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__distinct",
TypeAttributes.Public,
typeof(object));
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
// return;
il.Emit(OpCodes.Ret);
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new Type[] { typeof(object), typeof(object) });
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
LocalBuilder v = emitter.CreateLocal(typeof(int));
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(a);
emitter.LoadArgument(2);
emitter.CastAs(objectType);
emitter.StoreLocal(b);
emitter.Load(0);
emitter.StoreLocal(v);
Label end = emitter.CreateLabel();
for (int i = 0; i < props.Length; ++i)
{
if (i > 0)
{
emitter.LoadLocal(v);
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
}
Property prop = props[i];
emitter.LoadLocal(a);
emitter.Chain(prop);
bool couldCompare =
emitter.CompareTo(1, delegate()
{
emitter.LoadLocal(b);
emitter.Chain(prop);
});
if (!couldCompare)
throw new InvalidOperationException("Property is not comparable.");
emitter.StoreLocal(v);
}
emitter.MarkLabel(end);
emitter.LoadLocal(v);
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
"Compare",
new Type[]
{
typeof(object),
typeof(object)
}));
compareMethod = emitter.Method;
}
#endregion
#endregion
#region IEqualityComparer
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));
#region Equals
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "Equals",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(bool),
/* params */ new Type[] { typeof(object), typeof(object) });
emitter.Generator.Emit(OpCodes.Ldarg_0);
emitter.Generator.Emit(OpCodes.Ldarg_1);
emitter.Generator.Emit(OpCodes.Ldarg_2);
emitter.Generator.Emit(OpCodes.Call, compareMethod);
emitter.Generator.Emit(OpCodes.Ldc_I4_0);
emitter.Generator.Emit(OpCodes.Ceq);
emitter.Generator.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
"Equals",
new Type[]
{
typeof(object),
typeof(object)
}));
}
#endregion
#region GetHashCode
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "GetHashCode",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new Type[] { typeof(object) });
LocalBuilder obj = emitter.CreateLocal(objectType);
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(obj);
for (int i = 0; i < props.Length; ++i)
{
Property prop = props[i];
emitter.LoadLocal(obj);
emitter.Chain(prop);
Type active = emitter.Active;
MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);
if (getHashCode == null)
getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);
if (active != typeof(int))
{
if (!active.IsValueType)
{
LocalBuilder value = emitter.AcquireTemp(active);
Label valueNotNull = emitter.CreateLabel();
Label done = emitter.CreateLabel();
emitter.StoreLocal(value);
emitter.LoadLocal(value);
emitter.BranchIfTrue(valueNotNull);
emitter.Load(0);
emitter.Pop(typeof(int));
emitter.Branch(done);
emitter.MarkLabel(valueNotNull);
emitter.LoadLocal(value);
emitter.Call(getHashCode);
emitter.ReleaseTemp(value);
emitter.MarkLabel(done);
}
else
{
emitter.Call(getHashCode);
}
}
if (i > 0)
emitter.Xor();
}
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
"GetHashCode",
new Type[]
{
typeof(object)
}));
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
}
}
}

View File

@@ -0,0 +1,186 @@
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace Server.Commands.Generic
{
public sealed class OrderInfo
{
private Property m_Property;
private int m_Order;
public Property Property
{
get
{
return this.m_Property;
}
set
{
this.m_Property = value;
}
}
public bool IsAscending
{
get
{
return (this.m_Order > 0);
}
set
{
this.m_Order = (value ? +1 : -1);
}
}
public bool IsDescending
{
get
{
return (this.m_Order < 0);
}
set
{
this.m_Order = (value ? -1 : +1);
}
}
public int Sign
{
get
{
return Math.Sign(this.m_Order);
}
set
{
this.m_Order = Math.Sign(value);
if (this.m_Order == 0)
throw new InvalidOperationException("Sign cannot be zero.");
}
}
public OrderInfo(Property property, bool isAscending)
{
this.m_Property = property;
this.IsAscending = isAscending;
}
}
public static class SortCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__sort",
TypeAttributes.Public,
typeof(object));
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
// return;
il.Emit(OpCodes.Ret);
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new Type[] { typeof(object), typeof(object) });
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
LocalBuilder v = emitter.CreateLocal(typeof(int));
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(a);
emitter.LoadArgument(2);
emitter.CastAs(objectType);
emitter.StoreLocal(b);
emitter.Load(0);
emitter.StoreLocal(v);
Label end = emitter.CreateLabel();
for (int i = 0; i < orders.Length; ++i)
{
if (i > 0)
{
emitter.LoadLocal(v);
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
}
OrderInfo orderInfo = orders[i];
Property prop = orderInfo.Property;
int sign = orderInfo.Sign;
emitter.LoadLocal(a);
emitter.Chain(prop);
bool couldCompare =
emitter.CompareTo(sign, delegate()
{
emitter.LoadLocal(b);
emitter.Chain(prop);
});
if (!couldCompare)
throw new InvalidOperationException("Property is not comparable.");
emitter.StoreLocal(v);
}
emitter.MarkLabel(end);
emitter.LoadLocal(v);
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
"Compare",
new Type[]
{
typeof(object),
typeof(object)
}));
compareMethod = emitter.Method;
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(30, "Distinct", -1, delegate() { return new DistinctExtension(); });
private readonly List<Property> m_Properties;
private IComparer m_Comparer;
public DistinctExtension()
{
this.m_Properties = new List<Property>();
}
public override ExtensionInfo Info
{
get
{
return ExtInfo;
}
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new Exception("Distinct extension may only be used in combination with an object conditional.");
foreach (Property prop in this.m_Properties)
{
prop.BindTo(baseType, PropertyAccess.Read);
prop.CheckAccess(from);
}
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
this.m_Comparer = DistinctCompiler.Compile(assembly, baseType, this.m_Properties.ToArray());
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid distinction syntax.");
int end = offset + size;
while (offset < end)
{
string binding = arguments[offset++];
this.m_Properties.Add(new Property(binding));
}
}
public override void Filter(ArrayList list)
{
if (this.m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
ArrayList copy = new ArrayList(list);
copy.Sort(this.m_Comparer);
list.Clear();
object last = null;
for (int i = 0; i < copy.Count; ++i)
{
object obj = copy[i];
if (last == null || this.m_Comparer.Compare(obj, last) != 0)
{
list.Add(obj);
last = obj;
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections;
namespace Server.Commands.Generic
{
public sealed class LimitExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(80, "Limit", 1, delegate() { return new LimitExtension(); });
private int m_Limit;
public LimitExtension()
{
}
public override ExtensionInfo Info
{
get
{
return ExtInfo;
}
}
public int Limit
{
get
{
return this.m_Limit;
}
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
this.m_Limit = Utility.ToInt32(arguments[offset]);
if (this.m_Limit < 0)
throw new Exception("Limit cannot be less than zero.");
}
public override void Filter(ArrayList list)
{
if (list.Count > this.m_Limit)
list.RemoveRange(this.m_Limit, list.Count - this.m_Limit);
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
public sealed class SortExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(40, "Order", -1, delegate() { return new SortExtension(); });
private readonly List<OrderInfo> m_Orders;
private IComparer m_Comparer;
public SortExtension()
{
this.m_Orders = new List<OrderInfo>();
}
public override ExtensionInfo Info
{
get
{
return ExtInfo;
}
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new Exception("The ordering extension may only be used in combination with an object conditional.");
foreach (OrderInfo order in this.m_Orders)
{
order.Property.BindTo(baseType, PropertyAccess.Read);
order.Property.CheckAccess(from);
}
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
this.m_Comparer = SortCompiler.Compile(assembly, baseType, this.m_Orders.ToArray());
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid ordering syntax.");
if (Insensitive.Equals(arguments[offset], "by"))
{
++offset;
--size;
if (size < 1)
throw new Exception("Invalid ordering syntax.");
}
int end = offset + size;
while (offset < end)
{
string binding = arguments[offset++];
bool isAscending = true;
if (offset < end)
{
string next = arguments[offset];
switch ( next.ToLower() )
{
case "+":
case "up":
case "asc":
case "ascending":
isAscending = true;
++offset;
break;
case "-":
case "down":
case "desc":
case "descending":
isAscending = false;
++offset;
break;
}
}
Property property = new Property(binding);
this.m_Orders.Add(new OrderInfo(property, isAscending));
}
}
public override void Filter(ArrayList list)
{
if (this.m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
list.Sort(this.m_Comparer);
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
namespace Server.Commands.Generic
{
public sealed class WhereExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(20, "Where", -1, delegate() { return new WhereExtension(); });
private ObjectConditional m_Conditional;
public WhereExtension()
{
}
public override ExtensionInfo Info
{
get
{
return ExtInfo;
}
}
public ObjectConditional Conditional
{
get
{
return this.m_Conditional;
}
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new InvalidOperationException("Insanity.");
this.m_Conditional.Compile(ref assembly);
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid condition syntax.");
this.m_Conditional = ObjectConditional.ParseDirect(from, arguments, offset, size);
}
public override bool IsValid(object obj)
{
return this.m_Conditional.CheckCondition(obj);
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections;
namespace Server.Commands.Generic
{
public class AreaCommandImplementor : BaseCommandImplementor
{
private static AreaCommandImplementor m_Instance;
public AreaCommandImplementor()
{
this.Accessors = new string[] { "Area", "Group" };
this.SupportRequirement = CommandSupport.Area;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Area <command> [condition]";
this.Description = "Invokes the command on all appropriate objects in a targeted area. Optional condition arguments can further restrict the set of objects.";
m_Instance = this;
}
public static AreaCommandImplementor Instance
{
get
{
return m_Instance;
}
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
BoundingBoxPicker.Begin(from, new BoundingBoxCallback(OnTarget), new object[] { command, args });
}
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, object state)
{
try
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
IPooledEnumerable eable;
if (items && mobiles)
eable = map.GetObjectsInBounds(rect);
else if (items)
eable = map.GetItemsInBounds(rect);
else if (mobiles)
eable = map.GetMobilesInBounds(rect);
else
return;
ArrayList objs = new ArrayList();
foreach (object obj in eable)
{
if (mobiles && obj is Mobile && !BaseCommand.IsAccessible(from, obj))
continue;
if (ext.IsValid(obj))
objs.Add(obj);
}
eable.Free();
ext.Filter(objs);
this.RunCommand(from, objs, command, args);
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,372 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
[Flags]
public enum CommandSupport
{
Single = 0x0001,
Global = 0x0002,
Online = 0x0004,
Multi = 0x0008,
Area = 0x0010,
Self = 0x0020,
Region = 0x0040,
Contained = 0x0080,
IPAddress = 0x0100,
All = Single | Global | Online | Multi | Area | Self | Region | Contained | IPAddress,
AllMobiles = All & ~Contained,
AllNPCs = All & ~(IPAddress | Online | Self | Contained),
AllItems = All & ~(IPAddress | Online | Self | Region),
Simple = Single | Multi,
Complex = Global | Online | Area | Region | Contained | IPAddress
}
public abstract class BaseCommandImplementor
{
private static List<BaseCommandImplementor> m_Implementors;
private readonly Dictionary<string, BaseCommand> m_Commands;
private string[] m_Accessors;
private AccessLevel m_AccessLevel;
private CommandSupport m_SupportRequirement;
private string m_Usage;
private string m_Description;
private bool m_SupportsConditionals;
public BaseCommandImplementor()
{
this.m_Commands = new Dictionary<string, BaseCommand>(StringComparer.OrdinalIgnoreCase);
}
public static List<BaseCommandImplementor> Implementors
{
get
{
if (m_Implementors == null)
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
return m_Implementors;
}
}
public bool SupportsConditionals
{
get
{
return this.m_SupportsConditionals;
}
set
{
this.m_SupportsConditionals = value;
}
}
public string[] Accessors
{
get
{
return this.m_Accessors;
}
set
{
this.m_Accessors = value;
}
}
public string Usage
{
get
{
return this.m_Usage;
}
set
{
this.m_Usage = value;
}
}
public string Description
{
get
{
return this.m_Description;
}
set
{
this.m_Description = value;
}
}
public AccessLevel AccessLevel
{
get
{
return this.m_AccessLevel;
}
set
{
this.m_AccessLevel = value;
}
}
public CommandSupport SupportRequirement
{
get
{
return this.m_SupportRequirement;
}
set
{
this.m_SupportRequirement = value;
}
}
public Dictionary<string, BaseCommand> Commands
{
get
{
return this.m_Commands;
}
}
public static void RegisterImplementors()
{
Register(new RegionCommandImplementor());
Register(new GlobalCommandImplementor());
Register(new OnlineCommandImplementor());
Register(new SingleCommandImplementor());
Register(new SerialCommandImplementor());
Register(new MultiCommandImplementor());
Register(new AreaCommandImplementor());
Register(new SelfCommandImplementor());
Register(new ContainedCommandImplementor());
Register(new IPAddressCommandImplementor());
Register(new RangeCommandImplementor());
Register(new ScreenCommandImplementor());
Register(new FacetCommandImplementor());
}
public static void Register(BaseCommandImplementor impl)
{
m_Implementors.Add(impl);
impl.Register();
}
public virtual void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
obj = null;
}
public virtual void Register(BaseCommand command)
{
for (int i = 0; i < command.Commands.Length; ++i)
this.m_Commands[command.Commands[i]] = command;
}
public bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles)
{
items = mobiles = false;
ObjectConditional cond = ObjectConditional.Empty;
foreach (BaseExtension check in ext)
{
if (check is WhereExtension)
{
cond = (check as WhereExtension).Conditional;
break;
}
}
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
switch ( command.ObjectTypes )
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if (condIsItem)
items = true;
if (condIsMobile)
mobiles = true;
break;
}
case ObjectTypes.Items:
{
if (condIsItem)
{
items = true;
}
else if (condIsMobile)
{
from.SendMessage("You may not use a mobile type condition for this command.");
return false;
}
break;
}
case ObjectTypes.Mobiles:
{
if (condIsMobile)
{
mobiles = true;
}
else if (condIsItem)
{
from.SendMessage("You may not use an item type condition for this command.");
return false;
}
break;
}
}
return true;
}
public void RunCommand(Mobile from, BaseCommand command, string[] args)
{
try
{
object obj = null;
this.Compile(from, command, ref args, ref obj);
this.RunCommand(from, obj, command, args);
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
public string GenerateArgString(string[] args)
{
if (args.Length == 0)
return "";
// NOTE: this does not preserve the case where quotation marks are used on a single word
StringBuilder sb = new StringBuilder();
for (int i = 0; i < args.Length; ++i)
{
if (i > 0)
sb.Append(' ');
if (args[i].IndexOf(' ') >= 0)
{
sb.Append('"');
sb.Append(args[i]);
sb.Append('"');
}
else
{
sb.Append(args[i]);
}
}
return sb.ToString();
}
public void RunCommand(Mobile from, object obj, BaseCommand command, string[] args)
{
// try
// {
CommandEventArgs e = new CommandEventArgs(from, command.Commands[0], this.GenerateArgString(args), args);
if (!command.ValidateArgs(this, e))
return;
bool flushToLog = false;
if (obj is ArrayList)
{
ArrayList list = (ArrayList)obj;
if (list.Count > 20)
CommandLogging.Enabled = false;
else if (list.Count == 0)
command.LogFailure("Nothing was found to use this command on.");
command.ExecuteList(e, list);
if (list.Count > 20)
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if (obj != null)
{
if (command.ListOptimized)
{
ArrayList list = new ArrayList();
list.Add(obj);
command.ExecuteList(e, list);
}
else
{
command.Execute(e, obj);
}
}
command.Flush(from, flushToLog);
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
public virtual void Process(Mobile from, BaseCommand command, string[] args)
{
this.RunCommand(from, command, args);
}
public virtual void Execute(CommandEventArgs e)
{
if (e.Length >= 1)
{
BaseCommand command = null;
this.m_Commands.TryGetValue(e.GetString(0), out command);
if (command == null)
{
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 1];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 1];
this.Process(e.Mobile, command, args);
}
}
else
{
e.Mobile.SendMessage("You must supply a command name.");
}
}
public void Register()
{
if (this.m_Accessors == null)
return;
for (int i = 0; i < this.m_Accessors.Length; ++i)
CommandSystem.Register(this.m_Accessors[i], this.m_AccessLevel, new CommandEventHandler(Execute));
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections;
using Server.Items;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class ContainedCommandImplementor : BaseCommandImplementor
{
public ContainedCommandImplementor()
{
this.Accessors = new string[] { "Contained" };
this.SupportRequirement = CommandSupport.Contained;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Contained <command> [condition]";
this.Description = "Invokes the command on all child items in a targeted container. Optional condition arguments can further restrict the set of objects.";
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], this.GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget(Mobile from, object targeted, object state)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if (command.ObjectTypes == ObjectTypes.Mobiles)
return; // sanity check
if (!(targeted is Container))
{
from.SendMessage("That is not a container.");
}
else
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if (!items)
{
from.SendMessage("This command only works on items.");
return;
}
Container cont = (Container)targeted;
Item[] found = cont.FindItemsByType(typeof(Item), true);
ArrayList list = new ArrayList();
for (int i = 0; i < found.Length; ++i)
{
if (ext.IsValid(found[i]))
list.Add(found[i]);
}
ext.Filter(list);
this.RunCommand(from, list, command, args);
}
catch (Exception e)
{
from.SendMessage(e.Message);
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace Server.Commands.Generic
{
public class FacetCommandImplementor : BaseCommandImplementor
{
public FacetCommandImplementor()
{
this.Accessors = new string[] { "Facet" };
this.SupportRequirement = CommandSupport.Area;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Facet <command> [condition]";
this.Description = "Invokes the command on all appropriate objects within your facet's map bounds. Optional condition arguments can further restrict the set of objects.";
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if (impl == null)
return;
Map map = from.Map;
if (map == null || map == Map.Internal)
return;
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0), new object[] { command, args });
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections;
namespace Server.Commands.Generic
{
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
this.Accessors = new string[] { "Global" };
this.SupportRequirement = CommandSupport.Global;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.Administrator;
this.Usage = "Global <command> [condition]";
this.Description = "Invokes the command on all appropriate objects in the world. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
ArrayList list = new ArrayList();
if (items)
{
foreach (Item item in World.Items.Values)
{
if (ext.IsValid(item))
list.Add(item);
}
}
if (mobiles)
{
foreach (Mobile mob in World.Mobiles.Values)
{
if (ext.IsValid(mob))
list.Add(mob);
}
}
ext.Filter(list);
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections;
using Server.Network;
namespace Server.Commands.Generic
{
public class IPAddressCommandImplementor : BaseCommandImplementor
{
public IPAddressCommandImplementor()
{
this.Accessors = new string[] { "IPAddress" };
this.SupportRequirement = CommandSupport.IPAddress;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.Administrator;
this.Usage = "IPAddress <command> [condition]";
this.Description = "Invokes the command on one mobile from each IP address that is logged in. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if (!mobiles) // sanity check
{
command.LogFailure("This command does not support items.");
return;
}
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
System.Collections.Generic.List<NetState> states = NetState.Instances;
for (int i = 0; i < states.Count; ++i)
{
NetState ns = (NetState)states[i];
Mobile mob = ns.Mobile;
if (mob != null && !addresses.Contains(ns.Address) && ext.IsValid(mob))
{
list.Add(mob);
addresses.Add(ns.Address);
}
}
ext.Filter(list);
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
this.Accessors = new string[] { "Multi", "m" };
this.SupportRequirement = CommandSupport.Multi;
this.AccessLevel = AccessLevel.Counselor;
this.Usage = "Multi <command>";
this.Description = "Invokes the command on multiple targeted objects.";
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], this.GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget(Mobile from, object targeted, object state)
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget), new object[] { command, args });
return;
}
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if (!(targeted is Item) && !(targeted is Mobile))
{
from.SendMessage("This command does not work on that.");
return;
}
break;
}
case ObjectTypes.Items:
{
if (!(targeted is Item))
{
from.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
this.RunCommand(from, targeted, command, args);
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget), new object[] { command, args });
}
}
}

View File

@@ -0,0 +1,262 @@
using System;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
public sealed class ObjectConditional
{
private static readonly Type typeofItem = typeof(Item);
private static readonly Type typeofMobile = typeof(Mobile);
private readonly Type m_ObjectType;
private readonly ICondition[][] m_Conditions;
private IConditional[] m_Conditionals;
public Type Type
{
get
{
return this.m_ObjectType;
}
}
public bool IsItem
{
get
{
return (this.m_ObjectType == null || this.m_ObjectType == typeofItem || this.m_ObjectType.IsSubclassOf(typeofItem));
}
}
public bool IsMobile
{
get
{
return (this.m_ObjectType == null || this.m_ObjectType == typeofMobile || this.m_ObjectType.IsSubclassOf(typeofMobile));
}
}
public static readonly ObjectConditional Empty = new ObjectConditional(null, null);
public bool HasCompiled
{
get
{
return (this.m_Conditionals != null);
}
}
public void Compile(ref AssemblyEmitter emitter)
{
if (emitter == null)
emitter = new AssemblyEmitter("__dynamic", false);
this.m_Conditionals = new IConditional[this.m_Conditions.Length];
for (int i = 0; i < this.m_Conditionals.Length; ++i)
this.m_Conditionals[i] = ConditionalCompiler.Compile(emitter, this.m_ObjectType, this.m_Conditions[i], i);
}
public bool CheckCondition(object obj)
{
if (this.m_ObjectType == null)
return true; // null type means no condition
if (!this.HasCompiled)
{
AssemblyEmitter emitter = null;
this.Compile(ref emitter);
}
for (int i = 0; i < this.m_Conditionals.Length; ++i)
{
if (this.m_Conditionals[i].Verify(obj))
return true;
}
return false; // all conditions false
}
public static ObjectConditional Parse(Mobile from, ref string[] args)
{
string[] conditionArgs = null;
for (int i = 0; i < args.Length; ++i)
{
if (Insensitive.Equals(args[i], "where"))
{
string[] origArgs = args;
args = new string[i];
for (int j = 0; j < args.Length; ++j)
args[j] = origArgs[j];
conditionArgs = new string[origArgs.Length - i - 1];
for (int j = 0; j < conditionArgs.Length; ++j)
conditionArgs[j] = origArgs[i + j + 1];
break;
}
}
return ParseDirect(from, conditionArgs, 0, conditionArgs.Length);
}
public static ObjectConditional ParseDirect(Mobile from, string[] args, int offset, int size)
{
if (args == null || size == 0)
return ObjectConditional.Empty;
int index = 0;
Type objectType = ScriptCompiler.FindTypeByName(args[offset + index], true);
if (objectType == null)
throw new Exception(String.Format("No type with that name ({0}) was found.", args[offset + index]));
++index;
List<ICondition[]> conditions = new List<ICondition[]>();
List<ICondition> current = new List<ICondition>();
current.Add(TypeCondition.Default);
while (index < size)
{
string cur = args[offset + index];
bool inverse = false;
if (Insensitive.Equals(cur, "not") || cur == "!")
{
inverse = true;
++index;
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
}
else if (Insensitive.Equals(cur, "or") || cur == "||")
{
if (current.Count > 1)
{
conditions.Add(current.ToArray());
current.Clear();
current.Add(TypeCondition.Default);
}
++index;
continue;
}
string binding = args[offset + index];
index++;
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
string oper = args[offset + index];
index++;
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
string val = args[offset + index];
index++;
Property prop = new Property(binding);
prop.BindTo(objectType, PropertyAccess.Read);
prop.CheckAccess(from);
ICondition condition = null;
switch ( oper )
{
#region Equality
case "=":
case "==":
case "is":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Equal, val);
break;
case "!=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.NotEqual, val);
break;
#endregion
#region Relational
case ">":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Greater, val);
break;
case "<":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Lesser, val);
break;
case ">=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.GreaterEqual, val);
break;
case "<=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.LesserEqual, val);
break;
#endregion
#region Strings
case "==~":
case "~==":
case "=~":
case "~=":
case "is~":
case "~is":
condition = new StringCondition(prop, inverse, StringOperator.Equal, val, true);
break;
case "!=~":
case "~!=":
condition = new StringCondition(prop, inverse, StringOperator.NotEqual, val, true);
break;
case "starts":
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, false);
break;
case "starts~":
case "~starts":
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, true);
break;
case "ends":
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, false);
break;
case "ends~":
case "~ends":
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, true);
break;
case "contains":
condition = new StringCondition(prop, inverse, StringOperator.Contains, val, false);
break;
case "contains~":
case "~contains":
condition = new StringCondition(prop, inverse, StringOperator.Contains, val, true);
break;
#endregion
}
if (condition == null)
throw new InvalidOperationException(String.Format("Unrecognized operator (\"{0}\").", oper));
current.Add(condition);
}
conditions.Add(current.ToArray());
return new ObjectConditional(objectType, conditions.ToArray());
}
public ObjectConditional(Type objectType, ICondition[][] conditions)
{
this.m_ObjectType = objectType;
this.m_Conditions = conditions;
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Network;
namespace Server.Commands.Generic
{
public class OnlineCommandImplementor : BaseCommandImplementor
{
public OnlineCommandImplementor()
{
this.Accessors = new string[] { "Online" };
this.SupportRequirement = CommandSupport.Online;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Online <command> [condition]";
this.Description = "Invokes the command on all mobiles that are currently logged in. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if (!mobiles) // sanity check
{
command.LogFailure("This command does not support items.");
return;
}
ArrayList list = new ArrayList();
List<NetState> states = NetState.Instances;
for (int i = 0; i < states.Count; ++i)
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
if (mob == null)
continue;
if (!BaseCommand.IsAccessible(from, mob))
continue;
if (ext.IsValid(mob))
list.Add(mob);
}
ext.Filter(list);
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
namespace Server.Commands.Generic
{
public class RangeCommandImplementor : BaseCommandImplementor
{
private static RangeCommandImplementor m_Instance;
public RangeCommandImplementor()
{
this.Accessors = new string[] { "Range" };
this.SupportRequirement = CommandSupport.Area;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Range <range> <command> [condition]";
this.Description = "Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
m_Instance = this;
}
public static RangeCommandImplementor Instance
{
get
{
return m_Instance;
}
}
public override void Execute(CommandEventArgs e)
{
if (e.Length >= 2)
{
int range = e.GetInt32(0);
if (range < 0)
{
e.Mobile.SendMessage("The range must not be negative.");
}
else
{
BaseCommand command = null;
this.Commands.TryGetValue(e.GetString(1), out command);
if (command == null)
{
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
this.Process(range, e.Mobile, command, args);
}
}
}
else
{
e.Mobile.SendMessage("You must supply a range and a command name.");
}
}
public void Process(int range, Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if (impl == null)
return;
Map map = from.Map;
if (map == null || map == Map.Internal)
return;
Point3D start = new Point3D(from.X - range, from.Y - range, from.Z);
Point3D end = new Point3D(from.X + range, from.Y + range, from.Z);
impl.OnTarget(from, map, start, end, new object[] { command, args });
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections;
namespace Server.Commands.Generic
{
public class RegionCommandImplementor : BaseCommandImplementor
{
public RegionCommandImplementor()
{
this.Accessors = new string[] { "Region" };
this.SupportRequirement = CommandSupport.Region;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Region <command> [condition]";
this.Description = "Invokes the command on all appropriate mobiles in your current region. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!this.CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
Region reg = from.Region;
ArrayList list = new ArrayList();
if (mobiles)
{
foreach (Mobile mob in reg.GetMobiles())
{
if (!BaseCommand.IsAccessible(from, mob))
continue;
if (ext.IsValid(mob))
list.Add(mob);
}
}
else
{
command.LogFailure("This command does not support items.");
return;
}
ext.Filter(list);
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
namespace Server.Commands.Generic
{
public class ScreenCommandImplementor : BaseCommandImplementor
{
public ScreenCommandImplementor()
{
this.Accessors = new string[] { "Screen" };
this.SupportRequirement = CommandSupport.Area;
this.SupportsConditionals = true;
this.AccessLevel = AccessLevel.GameMaster;
this.Usage = "Screen <command> [condition]";
this.Description = "Invokes the command on all appropriate objects in your screen. Optional condition arguments can further restrict the set of objects.";
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
RangeCommandImplementor impl = RangeCommandImplementor.Instance;
if (impl == null)
return;
impl.Process(18, from, command, args);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
namespace Server.Commands.Generic
{
public class SelfCommandImplementor : BaseCommandImplementor
{
public SelfCommandImplementor()
{
this.Accessors = new string[] { "Self" };
this.SupportRequirement = CommandSupport.Self;
this.AccessLevel = AccessLevel.Counselor;
this.Usage = "Self <command>";
this.Description = "Invokes the command on the commanding player.";
}
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
if (command.ObjectTypes == ObjectTypes.Items)
return; // sanity check
obj = from;
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
namespace Server.Commands.Generic
{
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
this.Accessors = new string[] { "Serial" };
this.SupportRequirement = CommandSupport.Single;
this.AccessLevel = AccessLevel.Counselor;
this.Usage = "Serial <serial> <command>";
this.Description = "Invokes the command on a single object by serial.";
}
public override void Execute(CommandEventArgs e)
{
if (e.Length >= 2)
{
Serial serial = e.GetInt32(0);
object obj = null;
if (serial.IsItem)
obj = World.FindItem(serial);
else if (serial.IsMobile)
obj = World.FindMobile(serial);
if (obj == null)
{
e.Mobile.SendMessage("That is not a valid serial.");
}
else
{
BaseCommand command = null;
this.Commands.TryGetValue(e.GetString(1), out command);
if (command == null)
{
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if (!(obj is Item) && !(obj is Mobile))
{
e.Mobile.SendMessage("This command does not work on that.");
return;
}
break;
}
case ObjectTypes.Items:
{
if (!(obj is Item))
{
e.Mobile.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(obj is Mobile))
{
e.Mobile.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
this.RunCommand(e.Mobile, obj, command, args);
}
}
}
else
{
e.Mobile.SendMessage("You must supply an object serial and a command name.");
}
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new string[] { "Single" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Single <command>";
Description = "Invokes the command on a single targeted object. This is the same as just invoking the command directly.";
}
public override void Register(BaseCommand command)
{
base.Register(command);
for (int i = 0; i < command.Commands.Length; ++i)
CommandSystem.Register(command.Commands[i], command.AccessLevel, new CommandEventHandler(Redirect));
}
public void Redirect(CommandEventArgs e)
{
BaseCommand command = null;
this.Commands.TryGetValue(e.Command, out command);
if (command == null)
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier.");
else if (e.Mobile.AccessLevel < command.AccessLevel)
e.Mobile.SendMessage("You do not have access to that command.");
else if (command.ValidateArgs(this, e))
this.Process(e.Mobile, command, e.Arguments);
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], this.GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget(Mobile from, object targeted, object state)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendLocalizedMessage(500447); // That is not accessible.
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if (!(targeted is Item) && !(targeted is Mobile))
{
from.SendMessage("This command does not work on that.");
return;
}
break;
}
case ObjectTypes.Items:
{
if (!(targeted is Item))
{
from.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
this.RunCommand(from, targeted, command, args);
}
}
}

1012
Scripts/Commands/Handlers.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,437 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Network;
using CommandInfo = Server.Commands.Docs.DocCommandEntry;
using CommandInfoSorter = Server.Commands.Docs.CommandEntrySorter;
namespace Server.Commands
{
public class HelpInfo
{
private static readonly Dictionary<string, CommandInfo> m_HelpInfos = new Dictionary<string, CommandInfo>();
private static List<CommandInfo> m_SortedHelpInfo = new List<CommandInfo>();//No need for SortedList cause it's only sorted once at creation...
public static Dictionary<string, CommandInfo> HelpInfos
{
get
{
return m_HelpInfos;
}
}
public static List<CommandInfo> SortedHelpInfo
{
get
{
return m_SortedHelpInfo;
}
}
[CallPriority(100)]
public static void Initialize()
{
CommandSystem.Register("HelpInfo", AccessLevel.Player, new CommandEventHandler(HelpInfo_OnCommand));
FillTable();
}
public static void FillTable()
{
List<CommandEntry> commands = new List<CommandEntry>(CommandSystem.Entries.Values);
List<CommandInfo> list = new List<CommandInfo>();
commands.Sort();
commands.Reverse();
Docs.Clean(commands);
for (int i = 0; i < commands.Count; ++i)
{
CommandEntry e = commands[i];
MethodInfo mi = e.Handler.Method;
object[] attrs = mi.GetCustomAttributes(typeof(UsageAttribute), false);
if (attrs.Length == 0)
continue;
UsageAttribute usage = attrs[0] as UsageAttribute;
attrs = mi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs.Length == 0)
continue;
DescriptionAttribute desc = attrs[0] as DescriptionAttribute;
if (usage == null || desc == null)
continue;
attrs = mi.GetCustomAttributes(typeof(AliasesAttribute), false);
AliasesAttribute aliases = (attrs.Length == 0 ? null : attrs[0] as AliasesAttribute);
string descString = desc.Description.Replace("<", "(").Replace(">", ")");
if (aliases == null)
list.Add(new CommandInfo(e.AccessLevel, e.Command, null, usage.Usage, descString));
else
{
list.Add(new CommandInfo(e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString));
for (int j = 0; j < aliases.Aliases.Length; j++)
{
string[] newAliases = new string[aliases.Aliases.Length];
aliases.Aliases.CopyTo(newAliases, 0);
newAliases[j] = e.Command;
list.Add(new CommandInfo(e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString));
}
}
}
for (int i = 0; i < TargetCommands.AllCommands.Count; ++i)
{
BaseCommand command = TargetCommands.AllCommands[i];
string usage = command.Usage;
string desc = command.Description;
if (usage == null || desc == null)
continue;
string[] cmds = command.Commands;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
for (int j = 0; j < aliases.Length; ++j)
aliases[j] = cmds[j + 1];
desc = desc.Replace("<", "(").Replace(">", ")");
if (command.Supports != CommandSupport.Single)
{
StringBuilder sb = new StringBuilder(50 + desc.Length);
sb.Append("Modifiers: ");
if ((command.Supports & CommandSupport.Global) != 0)
sb.Append("<i>Global</i>, ");
if ((command.Supports & CommandSupport.Online) != 0)
sb.Append("<i>Online</i>, ");
if ((command.Supports & CommandSupport.Region) != 0)
sb.Append("<i>Region</i>, ");
if ((command.Supports & CommandSupport.Contained) != 0)
sb.Append("<i>Contained</i>, ");
if ((command.Supports & CommandSupport.Multi) != 0)
sb.Append("<i>Multi</i>, ");
if ((command.Supports & CommandSupport.Area) != 0)
sb.Append("<i>Area</i>, ");
if ((command.Supports & CommandSupport.Self) != 0)
sb.Append("<i>Self</i>, ");
sb.Remove(sb.Length - 2, 2);
sb.Append("<br>");
sb.Append(desc);
desc = sb.ToString();
}
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
for (int j = 0; j < aliases.Length; j++)
{
string[] newAliases = new string[aliases.Length];
aliases.CopyTo(newAliases, 0);
newAliases[j] = cmd;
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
}
}
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
for (int i = 0; i < commandImpls.Count; ++i)
{
BaseCommandImplementor command = commandImpls[i];
string usage = command.Usage;
string desc = command.Description;
if (usage == null || desc == null)
continue;
string[] cmds = command.Accessors;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
for (int j = 0; j < aliases.Length; ++j)
aliases[j] = cmds[j + 1];
desc = desc.Replace("<", ")").Replace(">", ")");
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
for (int j = 0; j < aliases.Length; j++)
{
string[] newAliases = new string[aliases.Length];
aliases.CopyTo(newAliases, 0);
newAliases[j] = cmd;
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
}
}
list.Sort(new CommandInfoSorter());
m_SortedHelpInfo = list;
foreach (CommandInfo c in m_SortedHelpInfo)
{
if (!m_HelpInfos.ContainsKey(c.Name.ToLower()))
m_HelpInfos.Add(c.Name.ToLower(), c);
}
}
[Usage("HelpInfo [<command>]")]
[Description("Gives information on a specified command, or when no argument specified, displays a gump containing all commands")]
private static void HelpInfo_OnCommand(CommandEventArgs e)
{
if (e.Length > 0)
{
string arg = e.GetString(0).ToLower();
CommandInfo c;
if (m_HelpInfos.TryGetValue(arg, out c))
{
Mobile m = e.Mobile;
if (m.AccessLevel >= c.AccessLevel)
m.SendGump(new CommandInfoGump(c));
else
m.SendMessage("You don't have access to that command.");
return;
}
else
e.Mobile.SendMessage(String.Format("Command '{0}' not found!", arg));
}
e.Mobile.SendGump(new CommandListGump(0, e.Mobile, null));
}
public class CommandListGump : BaseGridGump
{
private const int EntriesPerPage = 15;
readonly int m_Page;
readonly List<CommandInfo> m_List;
public CommandListGump(int page, Mobile from, List<CommandInfo> list)
: base(30, 30)
{
this.m_Page = page;
if (list == null)
{
this.m_List = new List<CommandInfo>();
foreach (CommandInfo c in m_SortedHelpInfo)
{
if (from.AccessLevel >= c.AccessLevel)
this.m_List.Add(c);
}
}
else
this.m_List = list;
this.AddNewPage();
if (this.m_Page > 0)
this.AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
else
this.AddEntryHeader(20);
this.AddEntryHtml(160, this.Center(String.Format("Page {0} of {1}", this.m_Page + 1, (this.m_List.Count + EntriesPerPage - 1) / EntriesPerPage)));
if ((this.m_Page + 1) * EntriesPerPage < this.m_List.Count)
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight);
else
this.AddEntryHeader(20);
int last = (int)AccessLevel.Player - 1;
for (int i = this.m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < this.m_List.Count; ++i, ++line)
{
CommandInfo c = this.m_List[i];
if (from.AccessLevel >= c.AccessLevel)
{
if ((int)c.AccessLevel != last)
{
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, this.Color(c.AccessLevel.ToString(), 0xFF0000));
this.AddEntryHeader(20);
line++;
}
last = (int)c.AccessLevel;
this.AddNewLine();
this.AddEntryHtml(20 + this.OffsetSize + 160, c.Name);
this.AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight);
}
}
this.FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile m = sender.Mobile;
switch( info.ButtonID )
{
case 0:
{
m.CloseGump(typeof(CommandInfoGump));
break;
}
case 1:
{
if (this.m_Page > 0)
m.SendGump(new CommandListGump(this.m_Page - 1, m, this.m_List));
break;
}
case 2:
{
if ((this.m_Page + 1) * EntriesPerPage < m_SortedHelpInfo.Count)
m.SendGump(new CommandListGump(this.m_Page + 1, m, this.m_List));
break;
}
default:
{
int v = info.ButtonID - 3;
if (v >= 0 && v < this.m_List.Count)
{
CommandInfo c = this.m_List[v];
if (m.AccessLevel >= c.AccessLevel)
{
m.SendGump(new CommandInfoGump(c));
m.SendGump(new CommandListGump(this.m_Page, m, this.m_List));
}
else
{
m.SendMessage("You no longer have access to that command.");
m.SendGump(new CommandListGump(this.m_Page, m, null));
}
}
break;
}
}
}
}
public class CommandInfoGump : Gump
{
private CommandInfo m_Info;
public CommandInfoGump(CommandInfo info)
: this(info, 320, 210)
{
}
public CommandInfoGump(CommandInfo info, int width, int height)
: base(300, 50)
{
m_Info = info;
this.AddPage(0);
this.AddBackground(0, 0, width, height, 5054);
this.AddHtml(10, 10, width - 20, 20, this.Color(this.Center(info.Name), 0xFF0000), false, false);
this.AddHtml(10, height - 30, 50, 20, this.Color("Params:", 0x00FF00), false, false);
this.AddAlphaRegion(65, height - 34, 170, 28);
this.AddTextEntry(70, height - 30, 160, 20, 789, 0, "");
this.AddHtml(250, height - 30, 30, 20, this.Color("Go", 0x00FF00), false, false);
this.AddButton(280, height - 30, 0xFA6, 0xFA7, 99, GumpButtonType.Reply, 0);
StringBuilder sb = new StringBuilder();
sb.Append("Usage: ");
sb.Append(info.Usage.Replace("<", "(").Replace(">", ")"));
sb.Append("<BR>");
string[] aliases = info.Aliases;
if (aliases != null && aliases.Length != 0)
{
sb.Append(String.Format("Alias{0}: ", aliases.Length == 1 ? "" : "es"));
for (int i = 0; i < aliases.Length; ++i)
{
if (i != 0)
sb.Append(", ");
sb.Append(aliases[i]);
}
sb.Append("<BR>");
}
sb.Append("AccessLevel: ");
sb.Append(info.AccessLevel.ToString());
sb.Append("<BR>");
sb.Append("<BR>");
sb.Append(info.Description);
this.AddHtml(10, 40, width - 20, height - 80, sb.ToString(), false, true);
//AddImageTiled( 10, height - 30, width - 20, 20, 2624 );
//AddAlphaRegion( 10, height - 30, width - 20, 20 );
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 99)
try
{
Mobile from = sender.Mobile;
string command = CommandSystem.Prefix + m_Info.Name + " " + info.TextEntries[0].Text;
CommandSystem.Handle(from, command);
}
catch
{
}
//else close the gump silently
}
public string Color(string text, int color)
{
return String.Format("<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text);
}
public string Center(string text)
{
return String.Format("<CENTER>{0}</CENTER>", text);
}
}
}
}

158
Scripts/Commands/Logging.cs Normal file
View File

@@ -0,0 +1,158 @@
using System;
using System.IO;
using Server.Accounting;
namespace Server.Commands
{
public class CommandLogging
{
private static readonly char[] m_NotSafe = new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
private static StreamWriter m_Output;
private static bool m_Enabled = true;
public static bool Enabled
{
get
{
return m_Enabled;
}
set
{
m_Enabled = value;
}
}
public static StreamWriter Output
{
get
{
return m_Output;
}
}
public static void Initialize()
{
EventSink.Command += new CommandEventHandler(EventSink_Command);
if (!Directory.Exists("Logs"))
Directory.CreateDirectory("Logs");
string directory = "Logs/Commands";
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
try
{
m_Output = new StreamWriter(Path.Combine(directory, String.Format("{0}.log", DateTime.UtcNow.ToLongDateString())), true);
m_Output.AutoFlush = true;
m_Output.WriteLine("##############################");
m_Output.WriteLine("Log started on {0}", DateTime.UtcNow);
m_Output.WriteLine();
}
catch
{
}
}
public static object Format(object o)
{
if (o is Mobile)
{
Mobile m = (Mobile)o;
if (m.Account == null)
return String.Format("{0} (no account)", m);
else
return String.Format("{0} ('{1}')", m, m.Account.Username);
}
else if (o is Item)
{
Item item = (Item)o;
return String.Format("0x{0:X} ({1})", item.Serial.Value, item.GetType().Name);
}
return o;
}
public static void WriteLine(Mobile from, string format, params object[] args)
{
if (!m_Enabled)
return;
WriteLine(from, String.Format(format, args));
}
public static void WriteLine(Mobile from, string text)
{
if (!m_Enabled)
return;
try
{
m_Output.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
string path = Core.BaseDirectory;
Account acct = from.Account as Account;
string name = (acct == null ? from.Name : acct.Username);
AppendPath(ref path, "Logs");
AppendPath(ref path, "Commands");
AppendPath(ref path, from.AccessLevel.ToString());
path = Path.Combine(path, String.Format("{0}.log", name));
using (StreamWriter sw = new StreamWriter(path, true))
sw.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
}
catch
{
}
}
public static void AppendPath(ref string path, string toAppend)
{
path = Path.Combine(path, toAppend);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
public static string Safe(string ip)
{
if (ip == null)
return "null";
ip = ip.Trim();
if (ip.Length == 0)
return "empty";
bool isSafe = true;
for (int i = 0; isSafe && i < m_NotSafe.Length; ++i)
isSafe = (ip.IndexOf(m_NotSafe[i]) == -1);
if (isSafe)
return ip;
System.Text.StringBuilder sb = new System.Text.StringBuilder(ip);
for (int i = 0; i < m_NotSafe.Length; ++i)
sb.Replace(m_NotSafe[i], '_');
return sb.ToString();
}
public static void EventSink_Command(CommandEventArgs e)
{
WriteLine(e.Mobile, "{0} {1} used command '{2} {3}'", e.Mobile.AccessLevel, Format(e.Mobile), e.Command, e.ArgString);
}
public static void LogChangeProperty(Mobile from, object o, string name, string value)
{
WriteLine(from, "{0} {1} set property '{2}' of {3} to '{4}'", from.AccessLevel, Format(from), name, Format(o), value);
}
}
}

36
Scripts/Commands/Mark.cs Normal file
View File

@@ -0,0 +1,36 @@
using Server.Items;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Server.Commands
{
public class Mark
{
public static void Initialize()
{
CommandSystem.Register("Mark", AccessLevel.GameMaster, new CommandEventHandler(Mark_OnCommand));
}
[Usage("Mark [name]")]
[Description("Creates a marked rune at your location.")]
private static void Mark_OnCommand(CommandEventArgs e)
{
if (e.Arguments.Length <= 0)
{
e.Mobile.SendMessage("Usage: mark [RuneName]");
return;
}
var runeName = e.Arguments[0];
var rune = new RecallRune();
rune.Mark(e.Mobile);
rune.Name = rune.Description = runeName;
e.Mobile.AddToBackpack(rune);
e.Mobile.SendMessage(string.Format("Rune {0} added to your backpack.", runeName));
}
}
}

View File

@@ -0,0 +1,402 @@
using System;
using System.Collections;
using System.IO;
using Server.Diagnostics;
namespace Server.Commands
{
public class Profiling
{
public static void Initialize()
{
CommandSystem.Register("DumpTimers", AccessLevel.Administrator, new CommandEventHandler(DumpTimers_OnCommand));
CommandSystem.Register("CountObjects", AccessLevel.Administrator, new CommandEventHandler(CountObjects_OnCommand));
CommandSystem.Register("ProfileWorld", AccessLevel.Administrator, new CommandEventHandler(ProfileWorld_OnCommand));
CommandSystem.Register("TraceInternal", AccessLevel.Administrator, new CommandEventHandler(TraceInternal_OnCommand));
CommandSystem.Register("TraceExpanded", AccessLevel.Administrator, new CommandEventHandler(TraceExpanded_OnCommand));
CommandSystem.Register("WriteProfiles", AccessLevel.Administrator, new CommandEventHandler(WriteProfiles_OnCommand));
CommandSystem.Register("SetProfiles", AccessLevel.Administrator, new CommandEventHandler(SetProfiles_OnCommand));
}
[Usage("WriteProfiles")]
[Description("Generates a log files containing performance diagnostic information.")]
public static void WriteProfiles_OnCommand(CommandEventArgs e)
{
try
{
using (StreamWriter sw = new StreamWriter("profiles.log", true))
{
sw.WriteLine("# Dump on {0:f}", DateTime.UtcNow);
sw.WriteLine("# Core profiling for " + Core.ProfileTime);
sw.WriteLine("# Packet send");
BaseProfile.WriteAll(sw, PacketSendProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Packet receive");
BaseProfile.WriteAll(sw, PacketReceiveProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Timer");
BaseProfile.WriteAll(sw, TimerProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Gump response");
BaseProfile.WriteAll(sw, GumpProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Target response");
BaseProfile.WriteAll(sw, TargetProfile.Profiles);
sw.WriteLine();
}
}
catch
{
}
}
[Usage("SetProfiles [true | false]")]
[Description("Enables, disables, or toggles the state of core packet and timer profiling.")]
public static void SetProfiles_OnCommand(CommandEventArgs e)
{
if (e.Length == 1)
Core.Profiling = e.GetBoolean(0);
else
Core.Profiling = !Core.Profiling;
e.Mobile.SendMessage("Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled");
}
[Usage("DumpTimers")]
[Description("Generates a log file of all currently executing timers. Used for tracing timer leaks.")]
public static void DumpTimers_OnCommand(CommandEventArgs e)
{
try
{
using (StreamWriter sw = new StreamWriter("timerdump.log", true))
Timer.DumpInfo(sw);
}
catch
{
}
}
[Usage("CountObjects")]
[Description("Generates a log file detailing all item and mobile types in the world.")]
public static void CountObjects_OnCommand(CommandEventArgs e)
{
using (StreamWriter op = new StreamWriter("objects.log"))
{
Hashtable table = new Hashtable();
foreach (Item item in World.Items.Values)
{
Type type = item.GetType();
object o = (object)table[type];
if (o == null)
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList items = new ArrayList(table);
table.Clear();
foreach (Mobile m in World.Mobiles.Values)
{
Type type = m.GetType();
object o = (object)table[type];
if (o == null)
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList mobiles = new ArrayList(table);
items.Sort(new CountSorter());
mobiles.Sort(new CountSorter());
op.WriteLine("# Object count table generated on {0}", DateTime.UtcNow);
op.WriteLine();
op.WriteLine();
op.WriteLine("# Items:");
foreach (DictionaryEntry de in items)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key);
op.WriteLine();
op.WriteLine();
op.WriteLine("#Mobiles:");
foreach (DictionaryEntry de in mobiles)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key);
}
e.Mobile.SendMessage("Object table has been generated. See the file : <servuo root>/objects.log");
}
[Usage("TraceExpanded")]
[Description("Generates a log file describing all items using expanded memory.")]
public static void TraceExpanded_OnCommand(CommandEventArgs e)
{
Hashtable typeTable = new Hashtable();
foreach (Item item in World.Items.Values)
{
ExpandFlag flags = item.GetExpandFlags();
if ((flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag)) == 0)
continue;
Type itemType = item.GetType();
do
{
int[] countTable = typeTable[itemType] as int[];
if (countTable == null)
typeTable[itemType] = countTable = new int[9];
if ((flags & ExpandFlag.Name) != 0)
++countTable[0];
if ((flags & ExpandFlag.Items) != 0)
++countTable[1];
if ((flags & ExpandFlag.Bounce) != 0)
++countTable[2];
if ((flags & ExpandFlag.Holder) != 0)
++countTable[3];
if ((flags & ExpandFlag.Blessed) != 0)
++countTable[4];
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
++countTable[5];
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
++countTable[6];*/
if ((flags & ExpandFlag.Weight) != 0)
++countTable[7];
if ((flags & ExpandFlag.Spawner) != 0)
++countTable[8];
itemType = itemType.BaseType;
}
while (itemType != typeof(object));
}
try
{
using (StreamWriter op = new StreamWriter("expandedItems.log", true))
{
string[] names = new string[]
{
"Name",
"Items",
"Bounce",
"Holder",
"Blessed",
"TempFlag",
"SaveFlag",
"Weight",
"Spawner"
};
ArrayList list = new ArrayList(typeTable);
list.Sort(new CountSorter());
foreach (DictionaryEntry de in list)
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
op.WriteLine("# {0}", itemType.FullName);
for (int i = 0; i < countTable.Length; ++i)
{
if (countTable[i] > 0)
op.WriteLine("{0}\t{1:N0}", names[i], countTable[i]);
}
op.WriteLine();
}
}
}
catch
{
}
}
[Usage("TraceInternal")]
[Description("Generates a log file describing all items in the 'internal' map.")]
public static void TraceInternal_OnCommand(CommandEventArgs e)
{
int totalCount = 0;
Hashtable table = new Hashtable();
foreach (Item item in World.Items.Values)
{
if (item.Parent != null || item.Map != Map.Internal)
continue;
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
if (parms == null)
table[type] = parms = new int[] { 0, 0 };
parms[0]++;
parms[1] += item.Amount;
}
using (StreamWriter op = new StreamWriter("internal.log"))
{
op.WriteLine("# {0} items found", totalCount);
op.WriteLine("# {0} different types", table.Count);
op.WriteLine();
op.WriteLine();
op.WriteLine("Type\t\tCount\t\tAmount\t\tAvg. Amount");
foreach (DictionaryEntry de in table)
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
op.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0]);
}
}
}
[Usage("ProfileWorld")]
[Description("Prints the amount of data serialized for every object type in your world file.")]
public static void ProfileWorld_OnCommand(CommandEventArgs e)
{
ProfileWorld("items", "worldprofile_items.log");
ProfileWorld("mobiles", "worldprofile_mobiles.log");
}
public static void ProfileWorld(string type, string opFile)
{
try
{
ArrayList types = new ArrayList();
using (BinaryReader bin = new BinaryReader(new FileStream(String.Format("Saves/{0}/{0}.tdb", type), FileMode.Open, FileAccess.Read, FileShare.Read)))
{
int count = bin.ReadInt32();
for (int i = 0; i < count; ++i)
types.Add(ScriptCompiler.FindTypeByFullName(bin.ReadString()));
}
long total = 0;
Hashtable table = new Hashtable();
using (BinaryReader bin = new BinaryReader(new FileStream(String.Format("Saves/{0}/{0}.idx", type), FileMode.Open, FileAccess.Read, FileShare.Read)))
{
int count = bin.ReadInt32();
for (int i = 0; i < count; ++i)
{
int typeID = bin.ReadInt32();
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
while (objType != null && objType != typeof(object))
{
object obj = table[objType];
if (obj == null)
table[objType] = length;
else
table[objType] = length + (int)obj;
objType = objType.BaseType;
total += length;
}
}
}
ArrayList list = new ArrayList(table);
list.Sort(new CountSorter());
using (StreamWriter op = new StreamWriter(opFile))
{
op.WriteLine("# Profile of world {0}", type);
op.WriteLine("# Generated on {0}", DateTime.UtcNow);
op.WriteLine();
op.WriteLine();
foreach (DictionaryEntry de in list)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key);
}
}
catch
{
}
}
private class CountSorter : IComparer
{
public int Compare(object x, object y)
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = this.GetCount(a.Value);
int bCount = this.GetCount(b.Value);
int v = -aCount.CompareTo(bCount);
if (v == 0)
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
v = aType.FullName.CompareTo(bType.FullName);
}
return v;
}
private int GetCount(object obj)
{
if (obj is int)
return (int)obj;
if (obj is int[])
{
int[] list = (int[])obj;
int total = 0;
for (int i = 0; i < list.Length; ++i)
total += list[i];
return total;
}
return 0;
}
}
}
}

View File

@@ -0,0 +1,971 @@
#region References
using System;
using System.Reflection;
using CustomsFramework;
using Server.Commands;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Targeting;
using Server.Mobiles;
using CPA = Server.CommandPropertyAttribute;
#endregion
namespace Server.Commands
{
[Flags]
public enum PropertyAccess
{
Read = 0x01,
Write = 0x02,
ReadWrite = Read | Write
}
public class Properties
{
private static readonly Type _TypeOfCPA = typeof(CPA);
private static readonly Type _TypeOfSerial = typeof(Serial);
private static readonly Type _TypeOfCustomSerial = typeof(CustomSerial);
private static readonly Type _TypeOfType = typeof(Type);
private static readonly Type _TypeOfChar = typeof(Char);
private static readonly Type _TypeOfString = typeof(String);
private static readonly Type _TypeOfIDynamicEnum = typeof(IDynamicEnum);
private static readonly Type _TypeOfText = typeof(TextDefinition);
private static readonly Type _TypeOfTimeSpan = typeof(TimeSpan);
private static readonly Type _TypeOfParsable = typeof(ParsableAttribute);
private static readonly Type[] _ParseTypes = new[] {typeof(string)};
private static readonly object[] _ParseParams = new object[1];
private static readonly Type[] _NumericTypes = new[]
{
typeof(Byte), typeof(SByte), typeof(Int16), typeof(UInt16), typeof(Int32), typeof(UInt32), typeof(Int64),
typeof(UInt64)
};
public static void Initialize()
{
CommandSystem.Register("Props", AccessLevel.Counselor, Props_OnCommand);
}
public static CPA GetCPA(PropertyInfo p)
{
var attrs = p.GetCustomAttributes(_TypeOfCPA, false);
return attrs.Length == 0 ? null : attrs[0] as CPA;
}
public static PropertyInfo[] GetPropertyInfoChain(
Mobile m, Type type, string propertyString, PropertyAccess endAccess, ref string failReason)
{
var split = propertyString.Split('.');
if (split.Length == 0)
{
return null;
}
var info = new PropertyInfo[split.Length];
for (int i = 0; i < info.Length; ++i)
{
string propertyName = split[i];
if (CIEqual(propertyName, "current"))
{
continue;
}
var props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
bool isFinal = i == info.Length - 1;
PropertyAccess access = endAccess;
if (!isFinal)
{
access |= PropertyAccess.Read;
}
foreach (PropertyInfo p in props)
{
if (!CIEqual(p.Name, propertyName))
{
continue;
}
CPA attr = GetCPA(p);
if (attr == null)
{
failReason = String.Format("Property '{0}' not found.", propertyName);
return null;
}
if ((access & PropertyAccess.Read) != 0 && m.AccessLevel < attr.ReadLevel)
{
failReason = String.Format(
"You must be at least {0} to get the property '{1}'.", Mobile.GetAccessLevelName(attr.ReadLevel), propertyName);
return null;
}
if ((access & PropertyAccess.Write) != 0 && m.AccessLevel < attr.WriteLevel)
{
failReason = String.Format(
"You must be at least {0} to set the property '{1}'.", Mobile.GetAccessLevelName(attr.WriteLevel), propertyName);
return null;
}
if ((access & PropertyAccess.Read) != 0 && !p.CanRead)
{
failReason = String.Format("Property '{0}' is write only.", propertyName);
return null;
}
if ((access & PropertyAccess.Write) != 0 && (!p.CanWrite || attr.ReadOnly) && isFinal)
{
failReason = String.Format("Property '{0}' is read only.", propertyName);
return null;
}
info[i] = p;
type = p.PropertyType;
break;
}
if (info[i] != null)
{
continue;
}
failReason = String.Format("Property '{0}' not found.", propertyName);
return null;
}
return info;
}
public static PropertyInfo GetPropertyInfo(
Mobile m, ref object obj, string propertyName, PropertyAccess access, ref string failReason)
{
var chain = GetPropertyInfoChain(m, obj.GetType(), propertyName, access, ref failReason);
return chain == null ? null : GetPropertyInfo(ref obj, chain, ref failReason);
}
public static PropertyInfo GetPropertyInfo(ref object obj, PropertyInfo[] chain, ref string failReason)
{
if (chain == null || chain.Length == 0)
{
failReason = "Property chain is empty.";
return null;
}
for (int i = 0; i < chain.Length - 1; ++i)
{
if (chain[i] == null)
{
continue;
}
obj = chain[i].GetValue(obj, null);
if (obj != null)
{
continue;
}
failReason = String.Format("Property '{0}' is null.", chain[i]);
return null;
}
return chain[chain.Length - 1];
}
public static string GetValue(Mobile from, object o, string name)
{
string failReason = "";
var chain = GetPropertyInfoChain(from, o.GetType(), name, PropertyAccess.Read, ref failReason);
if (chain == null || chain.Length == 0)
{
return failReason;
}
PropertyInfo p = GetPropertyInfo(ref o, chain, ref failReason);
return p == null ? failReason : InternalGetValue(o, p, chain);
}
public static string IncreaseValue(Mobile m, object o, string[] args)
{
int len = args.Length / 2;
var realObjs = new object[len];
var realProps = new PropertyInfo[len];
var realValues = new int[len];
bool positive = false, negative = false;
for (int i = 0; i < realProps.Length; ++i)
{
int idx = i * 2;
string name = args[idx];
try
{
string valueString = args[1 + idx];
if (valueString.StartsWith("0x"))
{
realValues[i] = Convert.ToInt32(valueString.Substring(2), 16);
}
else
{
realValues[i] = Convert.ToInt32(valueString);
}
}
catch
{
return "Offset value could not be parsed.";
}
if (realValues[i] > 0)
{
positive = true;
}
else if (realValues[i] < 0)
{
negative = true;
}
else
{
return "Zero is not a valid value to offset.";
}
string failReason = null;
realObjs[i] = o;
realProps[i] = GetPropertyInfo(m, ref realObjs[i], name, PropertyAccess.ReadWrite, ref failReason);
if (failReason != null)
{
return failReason;
}
if (realProps[i] == null)
{
return "Property not found.";
}
}
for (int i = 0; i < realProps.Length; ++i)
{
object obj = realProps[i].GetValue(realObjs[i], null);
if (!(obj is IConvertible))
{
return "Property is not IConvertable.";
}
try
{
long v = Convert.ToInt64(obj) + realValues[i];
object toSet = Convert.ChangeType(v, realProps[i].PropertyType);
realProps[i].SetValue(realObjs[i], toSet, null);
EventSink.InvokeOnPropertyChanged(new OnPropertyChangedEventArgs(m, realObjs[i], realProps[i], obj, toSet));
}
catch
{
return "Value could not be converted";
}
}
if (realProps.Length == 1)
{
return String.Format("The property has been {0}.", positive ? "increased." : "decreased");
}
if (positive && negative)
{
return "The properties have been changed.";
}
return String.Format("The properties have been {0}.", positive ? "increased." : "decreased");
}
public static string SetValue(Mobile m, object o, string name, string value)
{
object logObject = o;
string failReason = "";
PropertyInfo p = GetPropertyInfo(m, ref o, name, PropertyAccess.Write, ref failReason);
return p == null ? failReason : InternalSetValue(m, logObject, o, p, name, value, true);
}
public static string ConstructFromString(Type type, object obj, string value, ref object constructed)
{
object toSet;
bool isSerial = IsSerial(type);
bool isCustomSerial = IsCustomSerial(type);
if (isSerial || isCustomSerial) // mutate into int32
{
type = _NumericTypes[4];
}
if (value == "(-null-)" && !type.IsValueType)
{
value = null;
}
if (IsEnum(type))
{
try
{
toSet = Enum.Parse(type, value ?? String.Empty, true);
}
catch
{
return "That is not a valid enumeration member.";
}
}
else if (IsType(type))
{
try
{
toSet = ScriptCompiler.FindTypeByName(value);
if (toSet == null)
{
return "No type with that name was found.";
}
}
catch
{
return "No type with that name was found.";
}
}
else if (IsParsable(type))
{
try
{
toSet = Parse(obj, type, value);
}
catch
{
return "That is not properly formatted.";
}
}
else if (value == null)
{
toSet = null;
}
else if (value.StartsWith("0x") && IsNumeric(type))
{
try
{
toSet = Convert.ChangeType(Convert.ToUInt64(value.Substring(2), 16), type);
}
catch
{
return "That is not properly formatted.";
}
}
else
{
try
{
toSet = Convert.ChangeType(value, type);
}
catch
{
return "That is not properly formatted.";
}
}
if (isSerial) // mutate back
{
toSet = (Serial)Convert.ToInt32(toSet);
}
else if (isCustomSerial)
{
toSet = (CustomSerial)Convert.ToInt32(toSet);
}
constructed = toSet;
return null;
}
public static string SetDirect(
Mobile m, object logObject, object obj, PropertyInfo prop, string givenName, object toSet, bool shouldLog)
{
try
{
if (toSet is AccessLevel)
{
AccessLevel newLevel = (AccessLevel)toSet;
AccessLevel reqLevel = AccessLevel.Administrator;
if (newLevel == AccessLevel.Administrator)
{
reqLevel = AccessLevel.Developer;
}
else if (newLevel >= AccessLevel.Developer)
{
reqLevel = AccessLevel.Owner;
}
if (m.AccessLevel < reqLevel)
{
return "You do not have access to that level.";
}
}
if (shouldLog)
{
CommandLogging.LogChangeProperty(m, logObject, givenName, toSet == null ? "(-null-)" : toSet.ToString());
}
if (obj is PlayerMobile && prop.PropertyType == typeof(Map) && toSet == null)
{
return "Invalid -null- value, propery not set.";
}
object oldValue = prop.GetValue(obj, null);
prop.SetValue(obj, toSet, null);
EventSink.InvokeOnPropertyChanged(new OnPropertyChangedEventArgs(m, obj, prop, oldValue, toSet));
return "Property has been set.";
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
return "An exception was caught, the property may not be set.";
}
}
public static string SetDirect(object obj, PropertyInfo prop, object toSet)
{
try
{
if (toSet is AccessLevel)
{
return "You do not have access to that level.";
}
if (obj is PlayerMobile && prop.PropertyType == typeof(Map) && toSet == null)
{
return "Invalid -null- value, propery not set.";
}
object oldValue = prop.GetValue(obj, null);
prop.SetValue(obj, toSet, null);
EventSink.InvokeOnPropertyChanged(new OnPropertyChangedEventArgs(null, obj, prop, oldValue, toSet));
return "Property has been set.";
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return "An exception was caught, the property may not be set.";
}
}
public static string InternalSetValue(
Mobile m, object logobj, object o, PropertyInfo p, string pname, string value, bool shouldLog)
{
IDynamicEnum toSet;
object toSetObj = null;
string result = null;
if (IsIDynamicEnum(p.PropertyType))
{
toSetObj = toSet = p.GetValue(o, null) as IDynamicEnum;
if (toSet != null)
{
toSet.Value = value;
if (!toSet.IsValid)
{
result = "No type with that name was found.";
}
}
else
{
result = "That is not properly formatted.";
}
}
else
{
result = ConstructFromString(p.PropertyType, o, value, ref toSetObj);
}
return result ?? SetDirect(m, logobj, o, p, pname, toSetObj, shouldLog);
}
public static string InternalSetValue(object o, PropertyInfo p, string value)
{
IDynamicEnum toSet;
object toSetObj = null;
string result = null;
if (IsIDynamicEnum(p.PropertyType))
{
toSetObj = toSet = p.GetValue(o, null) as IDynamicEnum;
if (toSet != null)
{
toSet.Value = value;
if (!toSet.IsValid)
{
result = "No type with that name was found.";
}
}
else
{
result = "That is not properly formatted.";
}
}
else
{
result = ConstructFromString(p.PropertyType, o, value, ref toSetObj);
}
return result ?? SetDirect(o, p, toSetObj);
}
[Usage("Props [serial]")]
[Description("Opens a menu where you can view and edit all properties of a targeted (or specified) object.")]
private static void Props_OnCommand(CommandEventArgs e)
{
if (e.Length == 1)
{
IEntity ent = World.FindEntity(e.GetInt32(0));
if (ent == null)
{
e.Mobile.SendMessage("No object with that serial was found.");
}
else if (!BaseCommand.IsAccessible(e.Mobile, ent))
{
e.Mobile.SendMessage("That is not accessible.");
}
else
{
e.Mobile.SendGump(new PropertiesGump(e.Mobile, ent));
}
}
else
{
e.Mobile.Target = new PropsTarget();
}
}
private static bool CIEqual(string l, string r)
{
return Insensitive.Equals(l, r);
}
private static string InternalGetValue(object o, PropertyInfo p, PropertyInfo[] chain = null)
{
Type type = p.PropertyType;
object value = p.GetValue(o, null);
string toString;
if (value == null)
{
toString = "null";
}
else if (IsNumeric(type))
{
toString = String.Format("{0} (0x{0:X})", value);
}
else if (IsChar(type))
{
toString = String.Format("'{0}' ({1} [0x{1:X}])", value, (int)value);
}
else if (IsString(type))
{
toString = (string)value == "null" ? @"@""null""" : String.Format("\"{0}\"", value);
}
else if (IsIDynamicEnum(type))
{
toString = ((IDynamicEnum)value).Value == "null"
? @"@""null"""
: String.Format("\"{0}\"", ((IDynamicEnum)value).Value);
}
else if (IsText(type))
{
toString = ((TextDefinition)value).Format(false);
}
else
{
toString = value.ToString();
}
if (chain == null)
{
return String.Format("{0} = {1}", p.Name, toString);
}
var concat = new string[chain.Length * 2 + 1];
for (int i = 0; i < chain.Length; ++i)
{
int idx = i * 2;
concat[idx] = chain[i].Name;
concat[idx + 1] = i < chain.Length - 1 ? "." : " = ";
}
concat[concat.Length - 1] = toString;
return String.Concat(concat);
}
private static bool IsSerial(Type t)
{
return t == _TypeOfSerial;
}
private static bool IsCustomSerial(Type t)
{
return t == _TypeOfCustomSerial;
}
private static bool IsType(Type t)
{
return t == _TypeOfType;
}
private static bool IsChar(Type t)
{
return t == _TypeOfChar;
}
private static bool IsString(Type t)
{
return t == _TypeOfString;
}
private static bool IsIDynamicEnum(Type t)
{
return _TypeOfIDynamicEnum.IsAssignableFrom(t);
}
private static bool IsText(Type t)
{
return t == _TypeOfText;
}
private static bool IsEnum(Type t)
{
return t.IsEnum;
}
private static bool IsParsable(Type t)
{
return t == _TypeOfTimeSpan || t.IsDefined(_TypeOfParsable, false);
}
private static object Parse(object o, Type t, string value)
{
MethodInfo method = t.GetMethod("Parse", _ParseTypes);
_ParseParams[0] = value;
return method.Invoke(o, _ParseParams);
}
private static bool IsNumeric(Type t)
{
return Array.IndexOf(_NumericTypes, t) >= 0;
}
private class PropsTarget : Target
{
public PropsTarget()
: base(-1, true, TargetFlags.None)
{ }
protected override void OnTarget(Mobile from, object o)
{
if (!BaseCommand.IsAccessible(from, o))
{
from.SendMessage("That is not accessible.");
}
else
{
from.SendGump(new PropertiesGump(from, o));
}
}
}
}
}
namespace Server
{
public abstract class PropertyException : ApplicationException
{
public Property Property { get; protected set; }
public PropertyException(Property property, string message)
: base(message)
{
Property = property;
}
}
public abstract class BindingException : PropertyException
{
public BindingException(Property property, string message)
: base(property, message)
{ }
}
public sealed class NotYetBoundException : BindingException
{
public NotYetBoundException(Property property)
: base(property, String.Format("Property has not yet been bound."))
{ }
}
public sealed class AlreadyBoundException : BindingException
{
public AlreadyBoundException(Property property)
: base(property, String.Format("Property has already been bound."))
{ }
}
public sealed class UnknownPropertyException : BindingException
{
public UnknownPropertyException(Property property, string current)
: base(property, String.Format("Property '{0}' not found.", current))
{ }
}
public sealed class ReadOnlyException : BindingException
{
public ReadOnlyException(Property property)
: base(property, "Property is read-only.")
{ }
}
public sealed class WriteOnlyException : BindingException
{
public WriteOnlyException(Property property)
: base(property, "Property is write-only.")
{ }
}
public abstract class AccessException : PropertyException
{
public AccessException(Property property, string message)
: base(property, message)
{ }
}
public sealed class InternalAccessException : AccessException
{
public InternalAccessException(Property property)
: base(property, "Property is internal.")
{ }
}
public abstract class ClearanceException : AccessException
{
public AccessLevel PlayerAccess { get; protected set; }
public AccessLevel NeededAccess { get; protected set; }
public ClearanceException(Property property, AccessLevel playerAccess, AccessLevel neededAccess, string accessType)
: base(
property,
string.Format(
"You must be at least {0} to {1} this property, you are currently {2}.",
Mobile.GetAccessLevelName(neededAccess),
accessType,
Mobile.GetAccessLevelName(playerAccess)))
{ }
}
public sealed class ReadAccessException : ClearanceException
{
public ReadAccessException(Property property, AccessLevel playerAccess, AccessLevel neededAccess)
: base(property, playerAccess, neededAccess, "read")
{ }
}
public sealed class WriteAccessException : ClearanceException
{
public WriteAccessException(Property property, AccessLevel playerAccess, AccessLevel neededAccess)
: base(property, playerAccess, neededAccess, "write")
{ }
}
public sealed class Property
{
private PropertyInfo[] _Chain;
public PropertyAccess Access { get; private set; }
public string Binding { get; private set; }
public bool IsBound { get { return _Chain != null; } }
public PropertyInfo[] Chain
{
get
{
if (!IsBound)
{
throw new NotYetBoundException(this);
}
return _Chain;
}
}
public Type Type
{
get
{
if (!IsBound)
{
throw new NotYetBoundException(this);
}
return _Chain[_Chain.Length - 1].PropertyType;
}
}
public Property(string binding)
{
Binding = binding;
}
public Property(PropertyInfo[] chain)
{
_Chain = chain;
}
public static Property Parse(Type type, string binding, PropertyAccess access)
{
Property prop = new Property(binding);
prop.BindTo(type, access);
return prop;
}
public bool CheckAccess(Mobile from)
{
if (!IsBound)
{
throw new NotYetBoundException(this);
}
for (int i = 0; i < _Chain.Length; ++i)
{
PropertyAccess access = Access;
PropertyInfo prop = _Chain[i];
bool isFinal = i == _Chain.Length - 1;
if (!isFinal)
{
access |= PropertyAccess.Read;
}
CPA security = Properties.GetCPA(prop);
if (security == null)
{
throw new InternalAccessException(this);
}
if ((access & PropertyAccess.Read) != 0 && from.AccessLevel < security.ReadLevel)
{
throw new ReadAccessException(this, from.AccessLevel, security.ReadLevel);
}
if ((access & PropertyAccess.Write) != 0 && (from.AccessLevel < security.WriteLevel || security.ReadOnly))
{
throw new WriteAccessException(this, from.AccessLevel, security.ReadLevel);
}
}
return true;
}
public void BindTo(Type objectType, PropertyAccess desiredAccess)
{
if (IsBound)
{
throw new AlreadyBoundException(this);
}
var split = Binding.Split('.');
var chain = new PropertyInfo[split.Length];
for (int i = 0; i < split.Length; ++i)
{
bool isFinal = i == chain.Length - 1;
chain[i] = objectType.GetProperty(split[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
if (chain[i] == null)
{
throw new UnknownPropertyException(this, split[i]);
}
objectType = chain[i].PropertyType;
PropertyAccess access = desiredAccess;
if (!isFinal)
{
access |= PropertyAccess.Read;
}
if ((access & PropertyAccess.Read) != 0 && !chain[i].CanRead)
{
throw new WriteOnlyException(this);
}
if ((access & PropertyAccess.Write) != 0 && !chain[i].CanWrite)
{
throw new ReadOnlyException(this);
}
}
Access = desiredAccess;
_Chain = chain;
}
public override string ToString()
{
if (!IsBound)
{
return Binding;
}
var toJoin = new string[_Chain.Length];
for (int i = 0; i < toJoin.Length; ++i)
{
toJoin[i] = _Chain[i].Name;
}
return string.Join(".", toJoin);
}
}
}

View File

@@ -0,0 +1,269 @@
using System;
using Server.Items;
namespace Server.Commands
{
public class SHGenTeleporterDelete
{
public SHGenTeleporterDelete()
{
}
public static void Initialize()
{
CommandSystem.Register("SHTelGenDelete", AccessLevel.Administrator, new CommandEventHandler(SHTelGenDelete_OnCommand));
}
[Usage("SHTelGenDelete")]
[Description("Deletes solen hives teleporters.")]
public static void SHTelGenDelete_OnCommand(CommandEventArgs e)
{
World.Broadcast(0x35, true, "Solen hives teleporters are being deleted, please wait.");
DateTime startTime = DateTime.UtcNow;
int count = new SHTeleporterCreator().CreateSHTeleporters();
DateTime endTime = DateTime.UtcNow;
World.Broadcast(0x35, true, "{0} solen hives teleporters have been deleted. The entire process took {1:F1} seconds.", count, (endTime - startTime).TotalSeconds);
}
public class SHTeleporterCreator
{
private int m_Count;
public SHTeleporterCreator()
{
this.m_Count = 0;
}
public static SHTeleporter FindSHTeleporter(Map map, Point3D p)
{
IPooledEnumerable eable = map.GetItemsInRange(p, 0);
foreach (Item item in eable)
{
if (item is SHTeleporter && item.Z == p.Z)
{
eable.Free();
return (SHTeleporter)item;
}
}
eable.Free();
return null;
}
public SHTeleporter AddSHT(Map map, bool ext, int x, int y, int z)
{
Point3D p = new Point3D(x, y, z);
SHTeleporter tele = FindSHTeleporter(map, p);
if (tele != null)
{
/*tele = new SHTeleporter(ext);
tele.MoveToWorld(p, map);*/
this.m_Count++;
}
return tele;
}
/*public static void Link(SHTeleporter tele1, SHTeleporter tele2)
{
tele1.ChangeDest(tele2);
tele2.ChangeDest(tele1);
}*/
public void AddSHTCouple(Map map, bool ext1, int x1, int y1, int z1, bool ext2, int x2, int y2, int z2)
{
SHTeleporter tele1 = this.AddSHT(map, ext1, x1, y1, z1);
SHTeleporter tele2 = this.AddSHT(map, ext2, x2, y2, z2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
//Link(tele1, tele2);
}
public void AddSHTCouple(bool ext1, int x1, int y1, int z1, bool ext2, int x2, int y2, int z2)
{
this.AddSHTCouple(Map.Trammel, ext1, x1, y1, z1, ext2, x2, y2, z2);
this.AddSHTCouple(Map.Felucca, ext1, x1, y1, z1, ext2, x2, y2, z2);
}
public int CreateSHTeleporters()
{
SHTeleporter tele1, tele2;
this.AddSHTCouple(true, 2608, 763, 0, false, 5918, 1794, 0);
this.AddSHTCouple(false, 5897, 1877, 0, false, 5871, 1867, 0);
this.AddSHTCouple(false, 5852, 1848, 0, false, 5771, 1867, 0);
tele1 = this.AddSHT(Map.Trammel, false, 5747, 1895, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Trammel, false, 5658, 1898, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5747, 1895, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Felucca, false, 5658, 1898, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
this.AddSHTCouple(false, 5727, 1894, 0, false, 5756, 1794, 0);
this.AddSHTCouple(false, 5784, 1929, 0, false, 5700, 1929, 0);
tele1 = this.AddSHT(Map.Trammel, false, 5711, 1952, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Trammel, false, 5657, 1954, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5711, 1952, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Felucca, false, 5657, 1954, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Trammel, false, 5655, 2018, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Trammel, true, 1690, 2789, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5655, 2018, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Felucca, true, 1690, 2789, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
this.AddSHTCouple(false, 5809, 1905, 0, false, 5876, 1891, 0);
tele1 = this.AddSHT(Map.Trammel, false, 5814, 2015, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Trammel, false, 5913, 1893, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5814, 2015, 0);
//tele1.LeftTele.TeleOffset = new Point3D(-1, 3, 0);
tele2 = this.AddSHT(Map.Felucca, false, 5913, 1893, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
this.AddSHTCouple(false, 5919, 2021, 0, true, 1724, 814, 0);
tele1 = this.AddSHT(Map.Trammel, false, 5654, 1791, 0);
tele2 = this.AddSHT(Map.Trammel, true, 730, 1451, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Trammel, false, 5734, 1859, 0)/*.ChangeDest(tele2)*/;
if (tele1 != null)
{
tele1.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5654, 1791, 0);
tele2 = this.AddSHT(Map.Felucca, true, 730, 1451, 0);
//Link(tele1, tele2);
if (tele1 != null)
{
tele1.Delete();
}
if (tele2 != null)
{
tele2.Delete();
}
tele1 = this.AddSHT(Map.Felucca, false, 5734, 1859, 0)/*.ChangeDest(tele2)*/;
if (tele1 != null)
{
tele1.Delete();
}
return this.m_Count;
}
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace Server.Commands
{
public class ShardTime
{
public static void Initialize()
{
CommandSystem.Register( "Time", AccessLevel.Player, new CommandEventHandler( Time_OnCommand ) );
}
[Usage( "Time" )]
[Description( "Returns the server's local time." )]
private static void Time_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( DateTime.UtcNow.ToString() );
}
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server.Items;
namespace Server.Commands
{
public class SignParserDelete
{
private static readonly Queue<Item> m_ToDelete = new Queue<Item>();
public static void Initialize()
{
CommandSystem.Register("SignGenDelete", AccessLevel.Administrator, new CommandEventHandler(SignGenDelete_OnCommand));
}
[Usage("SignGenDelete")]
[Description("Deletes world/shop signs on all facets.")]
public static void SignGenDelete_OnCommand(CommandEventArgs c)
{
WeakEntityCollection.Delete("sign");
// Retained for backward compatibility
Parse(c.Mobile);
}
public static void Parse(Mobile from)
{
string cfg = Path.Combine(Core.BaseDirectory, "Data/signs.cfg");
if (File.Exists(cfg))
{
List<SignEntry> list = new List<SignEntry>();
from.SendMessage("Deleting signs, please wait.");
using (StreamReader ip = new StreamReader(cfg))
{
string line;
while ((line = ip.ReadLine()) != null)
{
string[] split = line.Split(' ');
SignEntry e = new SignEntry(
line.Substring(split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 + split[3].Length + 1 + split[4].Length + 1),
new Point3D(Utility.ToInt32(split[2]), Utility.ToInt32(split[3]), Utility.ToInt32(split[4])),
Utility.ToInt32(split[1]), Utility.ToInt32(split[0]));
list.Add(e);
}
}
Map[] brit = new Map[] { Map.Felucca, Map.Trammel };
Map[] fel = new Map[] { Map.Felucca };
Map[] tram = new Map[] { Map.Trammel };
Map[] ilsh = new Map[] { Map.Ilshenar };
Map[] malas = new Map[] { Map.Malas };
Map[] tokuno = new Map[] { Map.Tokuno };
for (int i = 0; i < list.Count; ++i)
{
SignEntry e = list[i];
Map[] maps = null;
switch ( e.m_Map )
{
case 0:
maps = brit;
break; // Trammel and Felucca
case 1:
maps = fel;
break; // Felucca
case 2:
maps = tram;
break; // Trammel
case 3:
maps = ilsh;
break; // Ilshenar
case 4:
maps = malas;
break; // Malas
case 5:
maps = tokuno;
break; // Tokuno Islands
}
for (int j = 0; maps != null && j < maps.Length; ++j)
Delete_Static(e.m_ItemID, e.m_Location, maps[j], e.m_Text);
}
from.SendMessage("Sign deleting complete.");
}
else
{
from.SendMessage("{0} not found!", cfg);
}
}
public static void Delete_Static(int itemID, Point3D location, Map map, string name)
{
IPooledEnumerable eable = map.GetItemsInRange(location, 0);
foreach (Item item in eable)
{
if (item is Sign && item.Z == location.Z && item.ItemID == itemID)
m_ToDelete.Enqueue(item);
}
eable.Free();
while (m_ToDelete.Count > 0)
m_ToDelete.Dequeue().Delete();
}
private class SignEntry
{
public readonly string m_Text;
public readonly Point3D m_Location;
public readonly int m_ItemID;
public readonly int m_Map;
public SignEntry(string text, Point3D pt, int itemID, int mapLoc)
{
this.m_Text = text;
this.m_Location = pt;
this.m_ItemID = itemID;
this.m_Map = mapLoc;
}
}
}
}

View File

@@ -0,0 +1,349 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server.Items;
using Server.Targeting;
using Server.Gumps;
using Server.Network;
namespace Server.Commands
{
public class SignParser
{
private static readonly Queue<Item> m_ToDelete = new Queue<Item>();
public static void Initialize()
{
CommandSystem.Register("SignGen", AccessLevel.Administrator, new CommandEventHandler(SignGen_OnCommand));
CommandSystem.Register("SignSave", AccessLevel.Administrator, new CommandEventHandler(SignSave_OnCommand));
CommandSystem.Register("SignRemove", AccessLevel.Administrator, new CommandEventHandler(SignRemove_OnCommand));
}
[Usage("SignRemove")]
[Description("Removes the targeted sign from the world and from the signs configuration file.")]
public static void SignRemove_OnCommand(CommandEventArgs c)
{
c.Mobile.Target = new SignRemoveTarget();
}
[Usage("SignSave")]
[Description("Saves the targeted sign to the signs configuration file.")]
public static void SignSave_OnCommand(CommandEventArgs c)
{
c.Mobile.Target = new SignSaveTarget();
}
[Usage("SignGen")]
[Description("Generates world/shop signs on all facets.")]
public static void SignGen_OnCommand(CommandEventArgs c)
{
Parse(c.Mobile);
}
public static void Parse(Mobile from)
{
from.SendMessage("Generating signs, please wait.");
List<SignEntry> list = SignEntry.LoadConfig("Data/signs.cfg");
Map[] brit = new Map[] { Map.Felucca, Map.Trammel };
Map[] fel = new Map[] { Map.Felucca };
Map[] tram = new Map[] { Map.Trammel };
Map[] ilsh = new Map[] { Map.Ilshenar };
Map[] malas = new Map[] { Map.Malas };
Map[] tokuno = new Map[] { Map.Tokuno };
for (int i = 0; i < list.Count; ++i)
{
SignEntry e = list[i];
Map[] maps = null;
switch ( e.m_Map )
{
case 0:
maps = brit;
break; // Trammel and Felucca
case 1:
maps = fel;
break; // Felucca
case 2:
maps = tram;
break; // Trammel
case 3:
maps = ilsh;
break; // Ilshenar
case 4:
maps = malas;
break; // Malas
case 5:
maps = tokuno;
break; // Tokuno Islands
}
for (int j = 0; maps != null && j < maps.Length; ++j)
Add_Static(e.m_ItemID, e.m_Location, maps[j], e.m_Text);
}
from.SendMessage("Sign generating complete.");
}
public static void Add_Static(int itemID, Point3D location, Map map, string name)
{
IPooledEnumerable eable = map.GetItemsInRange(location, 0);
foreach (Item item in eable)
{
if (item is Sign && item.Z == location.Z && item.ItemID == itemID)
m_ToDelete.Enqueue(item);
}
eable.Free();
while (m_ToDelete.Count > 0)
m_ToDelete.Dequeue().Delete();
Item sign;
if (name.StartsWith("#"))
{
sign = new LocalizedSign(itemID, Utility.ToInt32(name.Substring(1)));
}
else
{
sign = new Sign(itemID);
sign.Name = name;
}
WeakEntityCollection.Add("sign", sign);
if (map == Map.Malas)
{
if (location.X >= 965 && location.Y >= 502 && location.X <= 1012 && location.Y <= 537)
sign.Hue = 0x47E;
else if (location.X >= 1960 && location.Y >= 1278 && location.X < 2106 && location.Y < 1413)
sign.Hue = 0x44E;
}
sign.MoveToWorld(location, map);
}
private class SignEntry
{
public static readonly int BritMapId = 0;
public readonly string m_Text;
public readonly Point3D m_Location;
public readonly int m_ItemID;
public readonly int m_Map;
public SignEntry(string text, Point3D pt, int itemID, int mapLoc)
{
this.m_Text = text;
this.m_Location = pt;
this.m_ItemID = itemID;
this.m_Map = mapLoc;
}
public static int GetIdForMap(Map map)
{
if (map == Map.Felucca) return 1;
if (map == Map.Trammel) return 2;
if (map == Map.Ilshenar) return 3;
if (map == Map.Malas) return 4;
if (map == Map.Tokuno) return 5;
if (map == Map.TerMur) return 6;
throw new ArgumentException(String.Format("Unhandled map {0}", map.Name));
}
public static List<SignEntry> LoadConfig(String path)
{
List<SignEntry> list = new List<SignEntry>();
string cfg = Path.Combine(Core.BaseDirectory, path);
if (File.Exists(cfg))
{
using (StreamReader ip = new StreamReader(cfg))
{
string line;
while ((line = ip.ReadLine()) != null)
{
string[] split = line.Split(' ');
SignEntry e = new SignEntry(
line.Substring(split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 + split[3].Length + 1 + split[4].Length + 1),
new Point3D(Utility.ToInt32(split[2]), Utility.ToInt32(split[3]), Utility.ToInt32(split[4])),
Utility.ToInt32(split[1]), Utility.ToInt32(split[0]));
list.Add(e);
}
}
}
return list;
}
public static void WriteConfig(List<SignEntry> signs, String path)
{
string cfg = Path.Combine(Core.BaseDirectory, path);
using (StreamWriter op = new StreamWriter(cfg))
{
foreach(SignEntry sign in signs)
{
string line = String.Format("{0} {1} {2} {3} {4} {5}", sign.m_Map,
sign.m_ItemID, sign.m_Location.X, sign.m_Location.Y,
sign.m_Location.Z, sign.m_Text);
op.WriteLine(line);
}
}
}
}
private class SignRemoveTarget : Target
{
public SignRemoveTarget()
: base(-1, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object o)
{
if (!(o is Sign)) return;
Sign target = (Sign)o;
int targetMap = SignEntry.GetIdForMap(target.Map);
SignEntry toRemove = null;
List<SignEntry> signs = SignEntry.LoadConfig("Data/signs.cfg");
foreach(SignEntry sign in signs)
{
if(sign.m_Map == targetMap ||
(sign.m_Map == 0 && (
targetMap == 1 ||
targetMap == 2
)))
{
if(sign.m_Location.CompareTo(target.Location) == 0)
{
RemoveSign(target);
toRemove = sign;
}
}
}
if(toRemove != null)
{
signs.Remove(toRemove);
SignEntry.WriteConfig(signs, "Data/signs.cfg");
}
else
{
from.SendMessage("An entry for that sign was not found.");
}
}
private void RemoveSign(Sign sign)
{
IPooledEnumerable eable;
m_ToDelete.Enqueue(sign);
if (sign.Map == Map.Trammel)
{
eable = Map.Felucca.GetItemsInRange(sign.Location, 0);
foreach (Item item in eable)
{
if (item is Sign && item.Z == sign.Location.Z && item.ItemID == sign.ItemID)
m_ToDelete.Enqueue(item);
}
eable.Free();
}
if (sign.Map == Map.Felucca)
{
eable = Map.Trammel.GetItemsInRange(sign.Location, 0);
foreach (Item item in eable)
{
if (item is Sign && item.Z == sign.Location.Z && item.ItemID == sign.ItemID)
m_ToDelete.Enqueue(item);
}
eable.Free();
}
while (m_ToDelete.Count > 0)
m_ToDelete.Dequeue().Delete();
}
}
private class SignSaveTarget : Target
{
public int TargetMap { get; set; }
private Sign m_Sign;
private Mobile m_From;
public SignSaveTarget()
: base(-1, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object o)
{
if (!(o is Sign)) return;
m_Sign = (Sign)o;
m_From = from;
TargetMap = SignEntry.GetIdForMap(m_Sign.Map);
if(m_Sign.Map == Map.Felucca ||
m_Sign.Map == Map.Trammel)
{
from.SendGump(new BritGump(this));
}
else
{
DoSave();
}
}
public void DoSave()
{
List<SignEntry> signs = SignEntry.LoadConfig("Data/signs.cfg");
foreach(SignEntry sign in signs)
{
if(sign.m_Map == TargetMap &&
sign.m_Location.CompareTo(m_Sign.Location) == 0)
{
m_From.SendMessage("A sign is already configured for this location.");
return;
}
}
signs.Add(new SignEntry(m_Sign.Name, m_Sign.Location, m_Sign.ItemID, TargetMap));
SignEntry.WriteConfig(signs, "Data/signs.cfg");
}
}
private class BritGump : Gump
{
private SignSaveTarget m_Target;
public BritGump(SignSaveTarget target)
: base(30, 20)
{
this.m_Target = target;
this.Dragable = false;
this.Resizable = false;
this.Closable = false;
this.AddPage(0);
this.AddBackground(0, 0, 550, 440, 5054);
this.AddBackground(10, 10, 530, 420, 3000);
this.AddLabel(20, 20, 0, "Add this sign to both facets?");
this.AddButton(20, 40, 2453, 2454, 0, GumpButtonType.Reply, 0);
this.AddButton(450, 40, 2450, 2451, 1, GumpButtonType.Reply, 0);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if(info.ButtonID == 1)
{
m_Target.TargetMap = SignEntry.BritMapId;
}
m_Target.DoSave();
}
}
}
}

148
Scripts/Commands/Skills.cs Normal file
View File

@@ -0,0 +1,148 @@
using System;
using Server.Targeting;
namespace Server.Commands
{
public class SkillsCommand
{
public static void Initialize()
{
CommandSystem.Register("SetSkill", AccessLevel.GameMaster, new CommandEventHandler(SetSkill_OnCommand));
CommandSystem.Register("GetSkill", AccessLevel.GameMaster, new CommandEventHandler(GetSkill_OnCommand));
CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, new CommandEventHandler(SetAllSkills_OnCommand));
}
[Usage("SetSkill <name> <value>")]
[Description("Sets a skill value by name of a targeted mobile.")]
public static void SetSkill_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 2)
{
arg.Mobile.SendMessage("SetSkill <skill name> <value>");
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
{
arg.Mobile.Target = new SkillTarget(skill, arg.GetDouble(1));
}
else
{
arg.Mobile.SendLocalizedMessage(1005631); // You have specified an invalid skill to set.
}
}
}
[Usage("SetAllSkills <name> <value>")]
[Description("Sets all skill values of a targeted mobile.")]
public static void SetAllSkills_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 1)
{
arg.Mobile.SendMessage("SetAllSkills <value>");
}
else
{
arg.Mobile.Target = new AllSkillsTarget(arg.GetDouble(0));
}
}
[Usage("GetSkill <name>")]
[Description("Gets a skill value by name of a targeted mobile.")]
public static void GetSkill_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 1)
{
arg.Mobile.SendMessage("GetSkill <skill name>");
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
{
arg.Mobile.Target = new SkillTarget(skill);
}
else
{
arg.Mobile.SendMessage("You have specified an invalid skill to get.");
}
}
}
public class AllSkillsTarget : Target
{
private readonly double m_Value;
public AllSkillsTarget(double value)
: base(-1, false, TargetFlags.None)
{
this.m_Value = value;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
Server.Skills skills = targ.Skills;
for (int i = 0; i < skills.Length; ++i)
skills[i].Base = this.m_Value;
CommandLogging.LogChangeProperty(from, targ, "EverySkill.Base", this.m_Value.ToString());
}
else
{
from.SendMessage("That does not have skills!");
}
}
}
public class SkillTarget : Target
{
private readonly bool m_Set;
private readonly SkillName m_Skill;
private readonly double m_Value;
public SkillTarget(SkillName skill, double value)
: base(-1, false, TargetFlags.None)
{
this.m_Set = true;
this.m_Skill = skill;
this.m_Value = value;
}
public SkillTarget(SkillName skill)
: base(-1, false, TargetFlags.None)
{
this.m_Set = false;
this.m_Skill = skill;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
Skill skill = targ.Skills[this.m_Skill];
if (skill == null)
return;
if (this.m_Set)
{
skill.Base = this.m_Value;
CommandLogging.LogChangeProperty(from, targ, String.Format("{0}.Base", this.m_Skill), this.m_Value.ToString());
}
from.SendMessage("{0} : {1} (Base: {2})", this.m_Skill, skill.Value, skill.Base);
}
else
{
from.SendMessage("That does not have skills!");
}
}
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using Server.Gumps;
using Server.Targeting;
namespace Server.Commands
{
public class Skills
{
public static void Initialize()
{
Register();
}
public static void Register()
{
CommandSystem.Register("Skills", AccessLevel.Counselor, new CommandEventHandler(Skills_OnCommand));
}
[Usage("Skills")]
[Description("Opens a menu where you can view or edit skills of a targeted mobile.")]
private static void Skills_OnCommand(CommandEventArgs e)
{
e.Mobile.Target = new SkillsTarget();
}
private class SkillsTarget : Target
{
public SkillsTarget()
: base(-1, true, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object o)
{
if (o is Mobile)
from.SendGump(new SkillsGump(from, (Mobile)o));
}
}
}
}

569
Scripts/Commands/Statics.cs Normal file
View File

@@ -0,0 +1,569 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Server.Commands;
using Server.Gumps;
using Server.Items;
namespace Server
{
public class Statics
{
private static readonly Point3D NullP3D = new Point3D(int.MinValue, int.MinValue, int.MinValue);
private static byte[] m_Buffer;
private static StaticTile[] m_TileBuffer = new StaticTile[128];
private const string BaseFreezeWarning = "{0} " +
"Those items <u>will be removed from the world</u> and placed into the server data files. " +
"Other players <u>will not see the changes</u> unless you distribute your data files to them.<br><br>" +
"This operation may not complete unless the server and client are using different data files. " +
"If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " +
"Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.<br><br>" +
"The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " +
"It is strongly recommended that you make backup of the data files mentioned above. " +
"Do you wish to proceed?";
private const string BaseUnfreezeWarning = "{0} " +
"Those items <u>will be removed from the static files</u> and exchanged with unmovable dynamic items. " +
"Other players <u>will not see the changes</u> unless you distribute your data files to them.<br><br>" +
"This operation may not complete unless the server and client are using different data files. " +
"If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " +
"Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.<br><br>" +
"The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " +
"It is strongly recommended that you make backup of the data files mentioned above. " +
"Do you wish to proceed?";
public static void Initialize()
{
CommandSystem.Register("Freeze", AccessLevel.Administrator, new CommandEventHandler(Freeze_OnCommand));
CommandSystem.Register("FreezeMap", AccessLevel.Administrator, new CommandEventHandler(FreezeMap_OnCommand));
CommandSystem.Register("FreezeWorld", AccessLevel.Administrator, new CommandEventHandler(FreezeWorld_OnCommand));
CommandSystem.Register("Unfreeze", AccessLevel.Administrator, new CommandEventHandler(Unfreeze_OnCommand));
CommandSystem.Register("UnfreezeMap", AccessLevel.Administrator, new CommandEventHandler(UnfreezeMap_OnCommand));
CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, new CommandEventHandler(UnfreezeWorld_OnCommand));
}
[Usage("Freeze")]
[Description("Makes a targeted area of dynamic items static.")]
public static void Freeze_OnCommand(CommandEventArgs e)
{
BoundingBoxPicker.Begin(e.Mobile, new BoundingBoxCallback(FreezeBox_Callback), null);
}
[Usage("FreezeMap")]
[Description("Makes every dynamic item in your map static.")]
public static void FreezeMap_OnCommand(CommandEventArgs e)
{
Map map = e.Mobile.Map;
if (map != null && map != Map.Internal)
SendWarning(e.Mobile, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D, NullP3D, new WarningGumpCallback(FreezeWarning_Callback));
}
[Usage("FreezeWorld")]
[Description("Makes every dynamic item on all maps static.")]
public static void FreezeWorld_OnCommand(CommandEventArgs e)
{
SendWarning(e.Mobile, "You are about to freeze <u>every item on every map</u>.", BaseFreezeWarning, null, NullP3D, NullP3D, new WarningGumpCallback(FreezeWarning_Callback));
}
public static void SendWarning(Mobile m, string header, string baseWarning, Map map, Point3D start, Point3D end, WarningGumpCallback callback)
{
m.SendGump(new WarningGump(1060635, 30720, String.Format(baseWarning, String.Format(header, map)), 0xFFC000, 420, 400, callback, new StateInfo(map, start, end)));
}
public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d)
{
Hashtable mapTable = new Hashtable();
if (start3d == NullP3D && end3d == NullP3D)
{
if (targetMap == null)
CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in every map", from.AccessLevel, CommandLogging.Format(from));
else
CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in {0}", from.AccessLevel, CommandLogging.Format(from), targetMap);
foreach (Item item in World.Items.Values)
{
if (targetMap != null && item.Map != targetMap)
continue;
if (item.Parent != null)
continue;
if (item is Static || item is BaseFloor || item is BaseWall)
{
Map itemMap = item.Map;
if (itemMap == null || itemMap == Map.Internal)
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
if (table == null)
mapTable[itemMap] = table = new Hashtable();
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
DeltaState state = (DeltaState)table[p];
if (state == null)
table[p] = state = new DeltaState(p);
state.m_List.Add(item);
}
}
}
else if (targetMap != null)
{
Point2D start = targetMap.Bound(new Point2D(start3d)), end = targetMap.Bound(new Point2D(end3d));
CommandLogging.WriteLine(from, "{0} {1} invoking freeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format(from), start, end, targetMap);
IPooledEnumerable eable = targetMap.GetItemsInBounds(new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1));
foreach (Item item in eable)
{
if (item is Static || item is BaseFloor || item is BaseWall)
{
Map itemMap = item.Map;
if (itemMap == null || itemMap == Map.Internal)
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
if (table == null)
mapTable[itemMap] = table = new Hashtable();
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
DeltaState state = (DeltaState)table[p];
if (state == null)
table[p] = state = new DeltaState(p);
state.m_List.Add(item);
}
}
eable.Free();
}
if (mapTable.Count == 0)
{
from.SendGump(new NoticeGump(1060637, 30720, "No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall", 0xFFC000, 320, 240, null, null));
return;
}
bool badDataFile = false;
int totalFrozen = 0;
foreach (DictionaryEntry de in mapTable)
{
Map map = (Map)de.Key;
Hashtable table = (Hashtable)de.Value;
TileMatrix matrix = map.Tiles;
using (FileStream idxStream = OpenWrite(matrix.IndexStream))
{
using (FileStream mulStream = OpenWrite(matrix.DataStream))
{
if (idxStream == null || mulStream == null)
{
badDataFile = true;
continue;
}
BinaryReader idxReader = new BinaryReader(idxStream);
BinaryWriter idxWriter = new BinaryWriter(idxStream);
BinaryWriter mulWriter = new BinaryWriter(mulStream);
foreach (DeltaState state in table.Values)
{
int oldTileCount;
StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, state.m_X, state.m_Y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount);
if (oldTileCount < 0)
continue;
int newTileCount = 0;
StaticTile[] newTiles = new StaticTile[state.m_List.Count];
for (int i = 0; i < state.m_List.Count; ++i)
{
Item item = state.m_List[i];
int xOffset = item.X - (state.m_X * 8);
int yOffset = item.Y - (state.m_Y * 8);
if (xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8)
continue;
StaticTile newTile = new StaticTile((ushort)item.ItemID, (byte)xOffset, (byte)yOffset, (sbyte)item.Z, (short)item.Hue);
newTiles[newTileCount++] = newTile;
item.Delete();
++totalFrozen;
}
int mulPos = -1;
int length = -1;
int extra = 0;
if ((oldTileCount + newTileCount) > 0)
{
mulWriter.Seek(0, SeekOrigin.End);
mulPos = (int)mulWriter.BaseStream.Position;
length = (oldTileCount + newTileCount) * 7;
extra = 1;
for (int i = 0; i < oldTileCount; ++i)
{
StaticTile toWrite = oldTiles[i];
mulWriter.Write((ushort)toWrite.ID);
mulWriter.Write((byte)toWrite.X);
mulWriter.Write((byte)toWrite.Y);
mulWriter.Write((sbyte)toWrite.Z);
mulWriter.Write((short)toWrite.Hue);
}
for (int i = 0; i < newTileCount; ++i)
{
StaticTile toWrite = newTiles[i];
mulWriter.Write((ushort)toWrite.ID);
mulWriter.Write((byte)toWrite.X);
mulWriter.Write((byte)toWrite.Y);
mulWriter.Write((sbyte)toWrite.Z);
mulWriter.Write((short)toWrite.Hue);
}
mulWriter.Flush();
}
int idxPos = ((state.m_X * matrix.BlockHeight) + state.m_Y) * 12;
idxWriter.Seek(idxPos, SeekOrigin.Begin);
idxWriter.Write(mulPos);
idxWriter.Write(length);
idxWriter.Write(extra);
idxWriter.Flush();
matrix.SetStaticBlock(state.m_X, state.m_Y, null);
}
}
}
}
if (totalFrozen == 0 && badDataFile)
from.SendGump(new NoticeGump(1060637, 30720, "Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null));
else
from.SendGump(new NoticeGump(1060637, 30720, String.Format("Freeze operation completed successfully.<br><br>{0} item{1} frozen.<br><br>You must restart your client and update it's data files to see the changes.", totalFrozen, totalFrozen != 1 ? "s were" : " was"), 0xFFC000, 320, 240, null, null));
}
[Usage("Unfreeze")]
[Description("Makes a targeted area of static items dynamic.")]
public static void Unfreeze_OnCommand(CommandEventArgs e)
{
BoundingBoxPicker.Begin(e.Mobile, new BoundingBoxCallback(UnfreezeBox_Callback), null);
}
[Usage("UnfreezeMap")]
[Description("Makes every static item in your map dynamic.")]
public static void UnfreezeMap_OnCommand(CommandEventArgs e)
{
Map map = e.Mobile.Map;
if (map != null && map != Map.Internal)
SendWarning(e.Mobile, "You are about to unfreeze <u>all items in {0}</u>.", BaseUnfreezeWarning, map, NullP3D, NullP3D, new WarningGumpCallback(UnfreezeWarning_Callback));
}
[Usage("UnfreezeWorld")]
[Description("Makes every static item on all maps dynamic.")]
public static void UnfreezeWorld_OnCommand(CommandEventArgs e)
{
SendWarning(e.Mobile, "You are about to unfreeze <u>every item on every map</u>.", BaseUnfreezeWarning, null, NullP3D, NullP3D, new WarningGumpCallback(UnfreezeWarning_Callback));
}
public static void DoUnfreeze(Map map, ref bool badDataFile, ref int totalUnfrozen)
{
DoUnfreeze(map, Point2D.Zero, new Point2D(map.Width - 1, map.Height - 1), ref badDataFile, ref totalUnfrozen);
}
public static void Unfreeze(Mobile from, Map map, Point3D start, Point3D end)
{
int totalUnfrozen = 0;
bool badDataFile = false;
if (map == null)
{
CommandLogging.WriteLine(from, "{0} {1} invoking unfreeze for every item in every map", from.AccessLevel, CommandLogging.Format(from));
DoUnfreeze(Map.Felucca, ref badDataFile, ref totalUnfrozen);
DoUnfreeze(Map.Trammel, ref badDataFile, ref totalUnfrozen);
DoUnfreeze(Map.Ilshenar, ref badDataFile, ref totalUnfrozen);
DoUnfreeze(Map.Malas, ref badDataFile, ref totalUnfrozen);
DoUnfreeze(Map.Tokuno, ref badDataFile, ref totalUnfrozen);
}
else if (start == NullP3D && end == NullP3D)
{
CommandLogging.WriteLine(from, "{0} {1} invoking unfreeze for every item in {2}", from.AccessLevel, CommandLogging.Format(from), map);
DoUnfreeze(map, ref badDataFile, ref totalUnfrozen);
}
else
{
CommandLogging.WriteLine(from, "{0} {1} invoking unfreeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format(from), new Point2D(start), new Point2D(end), map);
DoUnfreeze(map, new Point2D(start), new Point2D(end), ref badDataFile, ref totalUnfrozen);
}
if (totalUnfrozen == 0 && badDataFile)
from.SendGump(new NoticeGump(1060637, 30720, "Output data files could not be opened and the unfreeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null));
else
from.SendGump(new NoticeGump(1060637, 30720, String.Format("Unfreeze operation completed successfully.<br><br>{0} item{1} unfrozen.<br><br>You must restart your client and update it's data files to see the changes.", totalUnfrozen, totalUnfrozen != 1 ? "s were" : " was"), 0xFFC000, 320, 240, null, null));
}
private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
SendWarning(from, "You are about to freeze a section of items.", BaseFreezeWarning, map, start, end, new WarningGumpCallback(FreezeWarning_Callback));
}
private static void FreezeWarning_Callback(Mobile from, bool okay, object state)
{
if (!okay)
return;
StateInfo si = (StateInfo)state;
Freeze(from, si.m_Map, si.m_Start, si.m_End);
}
private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
SendWarning(from, "You are about to unfreeze a section of items.", BaseUnfreezeWarning, map, start, end, new WarningGumpCallback(UnfreezeWarning_Callback));
}
private static void UnfreezeWarning_Callback(Mobile from, bool okay, object state)
{
if (!okay)
return;
StateInfo si = (StateInfo)state;
Unfreeze(from, si.m_Map, si.m_Start, si.m_End);
}
private static void DoUnfreeze(Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen)
{
start = map.Bound(start);
end = map.Bound(end);
int xStartBlock = start.X >> 3;
int yStartBlock = start.Y >> 3;
int xEndBlock = end.X >> 3;
int yEndBlock = end.Y >> 3;
int xTileStart = start.X, yTileStart = start.Y;
int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1;
TileMatrix matrix = map.Tiles;
using (FileStream idxStream = OpenWrite(matrix.IndexStream))
{
using (FileStream mulStream = OpenWrite(matrix.DataStream))
{
if (idxStream == null || mulStream == null)
{
badDataFile = true;
return;
}
BinaryReader idxReader = new BinaryReader(idxStream);
BinaryWriter idxWriter = new BinaryWriter(idxStream);
BinaryWriter mulWriter = new BinaryWriter(mulStream);
for (int x = xStartBlock; x <= xEndBlock; ++x)
{
for (int y = yStartBlock; y <= yEndBlock; ++y)
{
int oldTileCount;
StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, x, y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount);
if (oldTileCount < 0)
continue;
int newTileCount = 0;
StaticTile[] newTiles = new StaticTile[oldTileCount];
int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart;
for (int i = 0; i < oldTileCount; ++i)
{
StaticTile oldTile = oldTiles[i];
int px = baseX + oldTile.X;
int py = baseY + oldTile.Y;
if (px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight)
{
newTiles[newTileCount++] = oldTile;
}
else
{
++totalUnfrozen;
Item item = new Static(oldTile.ID);
item.Hue = oldTile.Hue;
item.MoveToWorld(new Point3D(px + xTileStart, py + yTileStart, oldTile.Z), map);
}
}
int mulPos = -1;
int length = -1;
int extra = 0;
if (newTileCount > 0)
{
mulWriter.Seek(0, SeekOrigin.End);
mulPos = (int)mulWriter.BaseStream.Position;
length = newTileCount * 7;
extra = 1;
for (int i = 0; i < newTileCount; ++i)
{
StaticTile toWrite = newTiles[i];
mulWriter.Write((ushort)toWrite.ID);
mulWriter.Write((byte)toWrite.X);
mulWriter.Write((byte)toWrite.Y);
mulWriter.Write((sbyte)toWrite.Z);
mulWriter.Write((short)toWrite.Hue);
}
mulWriter.Flush();
}
int idxPos = ((x * matrix.BlockHeight) + y) * 12;
idxWriter.Seek(idxPos, SeekOrigin.Begin);
idxWriter.Write(mulPos);
idxWriter.Write(length);
idxWriter.Write(extra);
idxWriter.Flush();
matrix.SetStaticBlock(x, y, null);
}
}
}
}
}
private static FileStream OpenWrite(FileStream orig)
{
if (orig == null)
return null;
try
{
return new FileStream(orig.Name, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
}
catch
{
return null;
}
}
private static StaticTile[] ReadStaticBlock(BinaryReader idxReader, FileStream mulStream, int x, int y, int width, int height, out int count)
{
try
{
if (x < 0 || x >= width || y < 0 || y >= height)
{
count = -1;
return m_TileBuffer;
}
idxReader.BaseStream.Seek(((x * height) + y) * 12, SeekOrigin.Begin);
int lookup = idxReader.ReadInt32();
int length = idxReader.ReadInt32();
if (lookup < 0 || length <= 0)
{
count = 0;
}
else
{
count = length / 7;
mulStream.Seek(lookup, SeekOrigin.Begin);
if (m_TileBuffer.Length < count)
m_TileBuffer = new StaticTile[count];
StaticTile[] staTiles = m_TileBuffer;
if (m_Buffer == null || length > m_Buffer.Length)
m_Buffer = new byte[length];
mulStream.Read(m_Buffer, 0, length);
int index = 0;
for (int i = 0; i < count; ++i)
{
staTiles[i].Set((ushort)(m_Buffer[index++] | (m_Buffer[index++] << 8)),
(byte)m_Buffer[index++], (byte)m_Buffer[index++], (sbyte)m_Buffer[index++],
(short)(m_Buffer[index++] | (m_Buffer[index++] << 8)));
}
}
}
catch
{
count = -1;
}
return m_TileBuffer;
}
private class DeltaState
{
public readonly int m_X;
public readonly int m_Y;
public readonly List<Item> m_List;
public DeltaState(Point2D p)
{
this.m_X = p.X;
this.m_Y = p.Y;
this.m_List = new List<Item>();
}
}
private class StateInfo
{
public readonly Map m_Map;
public readonly Point3D m_Start;
public readonly Point3D m_End;
public StateInfo(Map map, Point3D start, Point3D end)
{
this.m_Map = map;
this.m_Start = start;
this.m_End = end;
}
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace Server.Commands
{
public class TimeStamp
{
public static void Initialize()
{
CommandSystem.Register("TimeStamp", AccessLevel.Player, new CommandEventHandler(CheckTime_OnCommand));
}
[Usage("TimeStamp")]
[Description("Check's Your Servers Current Date And Time")]
public static void CheckTime_OnCommand(CommandEventArgs e)
{
Mobile m = e.Mobile;
DateTime now = DateTime.UtcNow;
m.SendMessage("The Current Date And Time Is " + now + "(EST)");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Commands
{
public class VisibilityList
{
public static void Initialize()
{
EventSink.Login += new LoginEventHandler(OnLogin);
CommandSystem.Register("Vis", AccessLevel.Counselor, new CommandEventHandler(Vis_OnCommand));
CommandSystem.Register("VisList", AccessLevel.Counselor, new CommandEventHandler(VisList_OnCommand));
CommandSystem.Register("VisClear", AccessLevel.Counselor, new CommandEventHandler(VisClear_OnCommand));
}
public static void OnLogin(LoginEventArgs e)
{
if (e.Mobile is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
pm.VisibilityList.Clear();
}
}
[Usage("Vis")]
[Description("Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden.")]
public static void Vis_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile)
{
e.Mobile.Target = new VisTarget();
e.Mobile.SendMessage("Select person to add or remove from your visibility list.");
}
}
[Usage("VisList")]
[Description("Shows the names of everyone in your visibility list.")]
public static void VisList_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = pm.VisibilityList;
if (list.Count > 0)
{
pm.SendMessage("You are visible to {0} mobile{1}:", list.Count, list.Count == 1 ? "" : "s");
for (int i = 0; i < list.Count; ++i)
pm.SendMessage("#{0}: {1}", i + 1, list[i].Name);
}
else
{
pm.SendMessage("Your visibility list is empty.");
}
}
}
[Usage("VisClear")]
[Description("Removes everyone from your visibility list.")]
public static void VisClear_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = new List<Mobile>(pm.VisibilityList);
pm.VisibilityList.Clear();
pm.SendMessage("Your visibility list has been cleared.");
for (int i = 0; i < list.Count; ++i)
{
Mobile m = list[i];
if (!m.CanSee(pm) && Utility.InUpdateRange(m, pm))
m.Send(pm.RemovePacket);
}
}
}
private class VisTarget : Target
{
public VisTarget()
: base(-1, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object targeted)
{
if (from is PlayerMobile && targeted is Mobile)
{
PlayerMobile pm = (PlayerMobile)from;
Mobile targ = (Mobile)targeted;
if (targ.AccessLevel <= from.AccessLevel)
{
List<Mobile> list = pm.VisibilityList;
if (list.Contains(targ))
{
list.Remove(targ);
from.SendMessage("{0} has been removed from your visibility list.", targ.Name);
}
else
{
list.Add(targ);
from.SendMessage("{0} has been added to your visibility list.", targ.Name);
}
if (Utility.InUpdateRange(targ, from))
{
NetState ns = targ.NetState;
if (ns != null)
{
if (targ.CanSee(from))
{
if (ns.StygianAbyss)
ns.Send(new MobileIncoming(targ, from));
else
ns.Send(new MobileIncomingOld(targ, from));
if (targ.ViewOPL)
{
ns.Send(from.OPLPacket);
foreach (Item item in from.Items)
ns.Send(item.OPLPacket);
}
}
else
{
ns.Send(from.RemovePacket);
}
}
}
}
else
{
from.SendMessage("They can already see you!");
}
}
else
{
from.SendMessage("Add only mobiles to your visibility list.");
}
}
}
}
}

103
Scripts/Commands/Wipe.cs Normal file
View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using Server.Items;
using Server.Multis;
namespace Server.Commands
{
public class Wipe
{
[Flags]
public enum WipeType
{
Items = 0x01,
Mobiles = 0x02,
Multis = 0x04,
All = Items | Mobiles | Multis
}
public static void Initialize()
{
CommandSystem.Register("Wipe", AccessLevel.GameMaster, new CommandEventHandler(WipeAll_OnCommand));
CommandSystem.Register("WipeItems", AccessLevel.GameMaster, new CommandEventHandler(WipeItems_OnCommand));
CommandSystem.Register("WipeNPCs", AccessLevel.GameMaster, new CommandEventHandler(WipeNPCs_OnCommand));
CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, new CommandEventHandler(WipeMultis_OnCommand));
}
public static void BeginWipe(Mobile from, WipeType type)
{
BoundingBoxPicker.Begin(from, new BoundingBoxCallback(WipeBox_Callback), type);
}
public static void DoWipe(Mobile from, Map map, Point3D start, Point3D end, WipeType type)
{
CommandLogging.WriteLine(from, "{0} {1} wiping from {2} to {3} in {5} ({4})", from.AccessLevel, CommandLogging.Format(from), start, end, type, map);
bool mobiles = ((type & WipeType.Mobiles) != 0);
bool multis = ((type & WipeType.Multis) != 0);
bool items = ((type & WipeType.Items) != 0);
List<IEntity> toDelete = new List<IEntity>();
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
IPooledEnumerable eable;
if ((items || multis) && mobiles)
eable = map.GetObjectsInBounds(rect);
else if (items || multis)
eable = map.GetItemsInBounds(rect);
else if (mobiles)
eable = map.GetMobilesInBounds(rect);
else
return;
foreach (IEntity obj in eable)
{
if (items && (obj is Item) && !((obj is BaseMulti) || (obj is HouseSign)))
toDelete.Add(obj);
else if (multis && (obj is BaseMulti))
toDelete.Add(obj);
else if (mobiles && (obj is Mobile) && !((Mobile)obj).Player)
toDelete.Add(obj);
}
eable.Free();
for (int i = 0; i < toDelete.Count; ++i)
toDelete[i].Delete();
}
[Usage("Wipe")]
[Description("Wipes all items and npcs in a targeted bounding box.")]
private static void WipeAll_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Items | WipeType.Mobiles);
}
[Usage("WipeItems")]
[Description("Wipes all items in a targeted bounding box.")]
private static void WipeItems_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Items);
}
[Usage("WipeNPCs")]
[Description("Wipes all npcs in a targeted bounding box.")]
private static void WipeNPCs_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Mobiles);
}
[Usage("WipeMultis")]
[Description("Wipes all multis in a targeted bounding box.")]
private static void WipeMultis_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Multis);
}
private static void WipeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
DoWipe(from, map, start, end, (WipeType)state);
}
}
}