Modernization Fixes & Updates to Default Values (#3)

This commit is contained in:
Kamron Batman 2018-10-28 00:33:16 -07:00 • committed by GitHub
parent 445eddff68
commit dcf64091b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
768 changed files with 10507 additions and 14196 deletions

View file

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Server.Items;
using Server.Targeting;
using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands
@ -54,18 +54,8 @@ namespace Server.Commands
CommandSystem.Register("OutlineAvg", AccessLevel.GameMaster, 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)
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs = null,
bool outline = false, bool mapAvg = false)
{
StringBuilder sb = new StringBuilder();
@ -148,13 +138,7 @@ namespace Server.Commands
}
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)
List<Container> packs, bool outline = false, bool mapAvg = false)
{
Utility.FixPoints(ref start, ref end);
@ -206,10 +190,19 @@ namespace Server.Commands
if (!IsConstructible(ctor, from.AccessLevel))
continue;
int totalParams = 0;
ParameterInfo[] paramList = ctor.GetParameters();
// Handle optional constructors
ParameterInfo[] paramList = ctor.GetParameters().Select(param =>
{
if (param.DefaultValue is DBNull)
totalParams += 1;
if (args.Length == paramList.Length)
return param;
}).ToArray();
if (args.Length == totalParams)
{
object[] paramValues = ParseValues(paramList, args);
@ -228,27 +221,31 @@ namespace Server.Commands
public static object[] ParseValues(ParameterInfo[] paramList, string[] args)
{
object[] values = new object[args.Length];
object[] values = new object[paramList.Length];
for (int i = 0; i < args.Length; ++i)
for (int i = 0, a = 0; i < paramList.Length; ++i)
{
object value = ParseValue(paramList[i].ParameterType, args[i]);
ParameterInfo param = paramList[i];
if (param.DefaultValue is DBNull)
{
object value = ParseValue(param.ParameterType, args[a++], param.DefaultValue);
if (value == null)
return null;
if (value != null)
values[i] = value;
}
else
return null;
values[i] = Type.Missing;
}
return values;
}
public static object ParseValue(Type type, string value)
public static object ParseValue(Type type, string value, object defaultValue)
{
try
{
if (IsEnum(type)) return Enum.Parse(type, value, true);
if (IsType(type)) return ScriptCompiler.FindTypeByName(value);
if (IsParsable(type)) return ParseParsable(type, value);
object obj = value;
@ -259,12 +256,13 @@ namespace Server.Commands
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);
else
obj = Convert.ToInt32(value.Substring(2), 16);
}
if (obj == null && !type.IsValueType)
return null;
return Convert.ChangeType(obj, type);
}
catch
@ -307,13 +305,7 @@ namespace Server.Commands
}
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)
string[,] props, PropertyInfo[] realProps, List<Container> packs, bool outline = false, bool mapAvg = false)
{
try
{
@ -352,7 +344,8 @@ namespace Server.Commands
if (built is Item item)
packs[i].DropItem(item);
else if (built is Mobile m) m.MoveToWorld(new Point3D(start.X, start.Y, start.Z), map);
else if (built is Mobile m)
m.MoveToWorld(new Point3D(start.X, start.Y, start.Z), map);
}
}
else
@ -374,7 +367,8 @@ namespace Server.Commands
if (built is Item item)
item.MoveToWorld(new Point3D(x, y, z), map);
else if (built is Mobile m) m.MoveToWorld(new Point3D(x, y, z), map);
else if (built is Mobile m)
m.MoveToWorld(new Point3D(x, y, z), map);
}
}
@ -437,9 +431,8 @@ namespace Server.Commands
from.SendMessage(sb.ToString());
}
private static void TileBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
private static void TileBox_Callback(Mobile from, Map map, Point3D start, Point3D end, TileState ts)
{
TileState ts = (TileState)state;
bool mapAvg = false;
switch (ts.m_ZType)
@ -461,10 +454,13 @@ namespace Server.Commands
private static void Internal_OnCommand(CommandEventArgs e, bool outline)
{
Mobile from = e.Mobile;
if (e.Length >= 1)
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback, new TileState(TileZType.Start, 0, e.Arguments, outline));
BoundingBoxPicker.Begin(from, (map, start, end) =>
TileBox_Callback(from, map, start, end, new TileState(TileZType.Start, 0, e.Arguments, outline)));
else
e.Mobile.SendMessage("Format: {0} <type> [params] [set {{<propertyName> <value> ...}}]",
from.SendMessage("Format: {0} <type> [params] [set {{<propertyName> <value> ...}}]",
outline ? "Outline" : "Tile");
}
@ -480,7 +476,7 @@ namespace Server.Commands
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 5];
Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
Invoke(e.Mobile, p, p2, subArgs, null, outline);
}
else
{
@ -502,7 +498,7 @@ namespace Server.Commands
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 5];
Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
Invoke(e.Mobile, p, p2, subArgs, null, outline);
}
else
{
@ -514,6 +510,8 @@ namespace Server.Commands
private static void InternalZ_OnCommand(CommandEventArgs e, bool outline)
{
Mobile from = e.Mobile;
if (e.Length >= 2)
{
string[] subArgs = new string[e.Length - 1];
@ -521,23 +519,25 @@ namespace Server.Commands
for (int i = 0; i < subArgs.Length; ++i)
subArgs[i] = e.Arguments[i + 1];
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback,
new TileState(TileZType.Fixed, e.GetInt32(0), subArgs, outline));
BoundingBoxPicker.Begin(from, (map, start, end) =>
TileBox_Callback(from, map, start, end, new TileState(TileZType.Fixed, e.GetInt32(0), subArgs, outline)));
}
else
{
e.Mobile.SendMessage("Format: {0}Z <z> <type> [params] [set {{<propertyName> <value> ...}}]",
from.SendMessage("Format: {0}Z <z> <type> [params] [set {{<propertyName> <value> ...}}]",
outline ? "Outline" : "Tile");
}
}
private static void InternalAvg_OnCommand(CommandEventArgs e, bool outline)
{
Mobile from = e.Mobile;
if (e.Length >= 1)
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback,
new TileState(TileZType.MapAverage, 0, e.Arguments, outline));
BoundingBoxPicker.Begin(from, (map, start, end) =>
TileBox_Callback(from, map, start, end, new TileState(TileZType.MapAverage, 0, e.Arguments, outline)));
else
e.Mobile.SendMessage("Format: {0}Avg <type> [params] [set {{<propertyName> <value> ...}}]",
from.SendMessage("Format: {0}Avg <type> [params] [set {{<propertyName> <value> ...}}]",
outline ? "Outline" : "Tile");
}
@ -657,7 +657,7 @@ namespace Server.Commands
m_ParseArgs[0] = value;
return method.Invoke(null, m_ParseArgs);
return method?.Invoke(null, m_ParseArgs);
}
public static bool IsSignedNumeric(Type type)
@ -678,30 +678,6 @@ namespace Server.Commands
return false;
}
public class AddTarget : Target
{
private string[] m_Args;
public AddTarget(string[] args) : base(-1, true, TargetFlags.None)
{
m_Args = args;
}
protected override void OnTarget(Mobile from, object o)
{
if (o is IPoint3D p)
{
if (p is Item item)
p = item.GetWorldTop();
else if (p is Mobile m)
p = m.Location;
Point3D point = new Point3D(p);
Add.Invoke(from, point, point, m_Args);
}
}
}
private enum TileZType
{
Start,

View file

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Server.Commands.Generic;
using Server.Gumps;
@ -13,18 +14,15 @@ namespace Server.Commands
{
Commands = new[] { "Batch" };
ListOptimized = true;
BatchCommands = new ArrayList();
Condition = "";
}
public BaseCommandImplementor Scope{ get; set; }
public string Condition{ get; set; }
public string Condition{ get; set; } = "";
public ArrayList BatchCommands{ get; }
public List<BatchCommand> BatchCommands{ get; } = new List<BatchCommand>();
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (list.Count == 0)
{
@ -39,7 +37,7 @@ namespace Server.Commands
for (int i = 0; i < BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)BatchCommands[i];
BatchCommand bc = BatchCommands[i];
bc.GetDetails(out string commandString, out string argString, out string[] args);
@ -68,12 +66,12 @@ namespace Server.Commands
for (int i = 0; i < commands.Length; ++i)
{
BaseCommand command = commands[i];
BatchCommand bc = (BatchCommand)BatchCommands[i];
BatchCommand bc = BatchCommands[i];
if (list.Count > 20)
CommandLogging.Enabled = false;
ArrayList usedList;
List<object> usedList;
if (Utility.InsensitiveCompare(bc.Object, "Current") == 0)
{
@ -81,9 +79,9 @@ namespace Server.Commands
}
else
{
Hashtable propertyChains = new Hashtable();
Dictionary<Type, PropertyInfo[]> propertyChains = new Dictionary<Type, PropertyInfo[]>();
usedList = new ArrayList(list.Count);
usedList = new List<object>(list.Count);
for (int j = 0; j < list.Count; ++j)
{
@ -94,11 +92,11 @@ namespace Server.Commands
Type type = obj.GetType();
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
PropertyInfo[] chain = propertyChains[type];
string failReason = "";
if (chain == null && !propertyChains.Contains(type))
if (chain == null)
propertyChains[type] = chain = Properties.GetPropertyInfoChain(e.Mobile, type, bc.Object,
PropertyAccess.Read, ref failReason);
@ -119,6 +117,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
}
@ -272,7 +271,7 @@ namespace Server.Commands
for (int i = 0; i < m_Batch.BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)m_Batch.BatchCommands[i];
BatchCommand bc = m_Batch.BatchCommands[i];
AddNewLine();
@ -420,4 +419,4 @@ namespace Server.Commands
m_From.SendGump(new BatchGump(m_From, m_Batch));
}
}
}
}

View file

@ -2,14 +2,14 @@ using Server.Targeting;
namespace Server
{
public delegate void BoundingBoxCallback(Mobile from, Map map, Point3D start, Point3D end, object state);
public delegate void BoundingBoxCallback(Map map, Point3D start, Point3D end);
public class BoundingBoxPicker
public static class BoundingBoxPicker
{
public static void Begin(Mobile from, BoundingBoxCallback callback, object state)
public static void Begin(Mobile from, BoundingBoxCallback callback)
{
from.SendMessage("Target the first location of the bounding box.");
from.Target = new PickTarget(callback, state);
from.Target = new PickTarget(callback);
}
private class PickTarget : Target
@ -17,21 +17,18 @@ namespace Server
private BoundingBoxCallback m_Callback;
private bool m_First;
private Map m_Map;
private object m_State;
private Point3D m_Store;
public PickTarget(BoundingBoxCallback callback, object state) : this(Point3D.Zero, true, null, callback, state)
public PickTarget(BoundingBoxCallback callback) : this(Point3D.Zero, true, null, callback)
{
}
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback, object state) : base(-1,
true, TargetFlags.None)
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback) : base(-1, true, TargetFlags.None)
{
m_Store = store;
m_First = first;
m_Map = map;
m_Callback = callback;
m_State = state;
}
protected override void OnTarget(Mobile from, object targeted)
@ -45,7 +42,7 @@ namespace Server
if (m_First)
{
from.SendMessage("Target another location to complete the bounding box.");
from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback, m_State);
from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback);
}
else if (from.Map != m_Map)
{
@ -58,7 +55,7 @@ namespace Server
Utility.FixPoints(ref start, ref end);
m_Callback(from, m_Map, start, end, m_State);
m_Callback(m_Map, start, end);
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Server.Mobiles;
using Server.Network;
@ -63,24 +64,22 @@ namespace Server.Commands
}
}
private static PropertyInfo[] _mobProps =
typeof(Mobile).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(prop => prop.CanRead && prop.CanWrite).ToArray();
private static void CopyProps(Mobile to, Mobile from)
{
Type type = typeof(Mobile);
PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int p = 0; p < props.Length; p++)
foreach (PropertyInfo prop in _mobProps)
{
PropertyInfo prop = props[p];
if (prop.CanRead && prop.CanWrite)
try
{
prop.SetValue(to, prop.GetValue(from, null), null);
}
catch
{
}
try
{
prop.SetValue(to, prop.GetValue(from, null), null);
}
catch
{
// ignored
}
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Server.Engines.Quests.Haven;
@ -47,10 +46,10 @@ namespace Server.Commands
for (int i = 0; i < files.Length; ++i)
{
ArrayList list = DecorationList.ReadAll(files[i]);
List<DecorationList> list = DecorationList.ReadAll(files[i]);
for (int j = 0; j < list.Count; ++j)
m_Count += ((DecorationList)list[j]).Generate(maps);
m_Count += list[j].Generate(maps);
}
}
}
@ -70,10 +69,10 @@ namespace Server.Commands
private static Type typeofCannon = typeof(Cannon);
private static Type typeofSerpentPillar = typeof(SerpentPillar);
private static Queue m_DeleteQueue = new Queue();
private static Queue<Item> m_DeleteQueue = new Queue<Item>();
private static string[] m_EmptyParams = new string[0];
private ArrayList m_Entries;
private List<DecorationEntry> m_Entries;
private int m_ItemID;
private string[] m_Params;
private Type m_Type;
@ -913,7 +912,7 @@ namespace Server.Commands
eable.Free();
while (m_DeleteQueue.Count > 0)
((Item)m_DeleteQueue.Dequeue()).Delete();
m_DeleteQueue.Dequeue().Delete();
return res;
}
@ -926,7 +925,7 @@ namespace Server.Commands
for (int i = 0; i < m_Entries.Count; ++i)
{
DecorationEntry entry = (DecorationEntry)m_Entries[i];
DecorationEntry entry = m_Entries[i];
Point3D loc = entry.Location;
string extra = entry.Extra;
@ -970,6 +969,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -983,13 +983,14 @@ namespace Server.Commands
return count;
}
public static ArrayList ReadAll(string path)
public static List<DecorationList> ReadAll(string path)
{
using (StreamReader ip = new StreamReader(path))
{
ArrayList list = new ArrayList();
for (DecorationList v = Read(ip); v != null; v = Read(ip))
List<DecorationList> list = new List<DecorationList>();
DecorationList v;
while ((v = Read(ip)) != null)
list.Add(v);
return list;
@ -1042,7 +1043,7 @@ namespace Server.Commands
list.m_Params = m_EmptyParams;
}
list.m_Entries = new ArrayList();
list.m_Entries = new List<DecorationEntry>();
while ((line = ip.ReadLine()) != null)
{

View file

@ -44,10 +44,10 @@ namespace Server.Commands
for (int i = 0; i < files.Length; ++i)
{
ArrayList list = DecorationListMag.ReadAll(files[i]);
List<DecorationListMag> list = DecorationListMag.ReadAll(files[i]);
for (int j = 0; j < list.Count; ++j)
m_Count += ((DecorationListMag)list[j]).Generate(maps);
m_Count += list[j].Generate(maps);
}
}
}
@ -70,7 +70,7 @@ namespace Server.Commands
private static Queue m_DeleteQueue = new Queue();
private static string[] m_EmptyParams = new string[0];
private ArrayList m_Entries;
private List<DecorationEntryMag> m_Entries;
private int m_ItemID;
private string[] m_Params;
private Type m_Type;
@ -923,7 +923,7 @@ namespace Server.Commands
for (int i = 0; i < m_Entries.Count; ++i)
{
DecorationEntryMag entry = (DecorationEntryMag)m_Entries[i];
DecorationEntryMag entry = m_Entries[i];
Point3D loc = entry.Location;
string extra = entry.Extra;
@ -967,6 +967,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -980,13 +981,14 @@ namespace Server.Commands
return count;
}
public static ArrayList ReadAll(string path)
public static List<DecorationListMag> ReadAll(string path)
{
using (StreamReader ip = new StreamReader(path))
{
ArrayList list = new ArrayList();
List<DecorationListMag> list = new List<DecorationListMag>();
for (DecorationListMag v = Read(ip); v != null; v = Read(ip))
DecorationListMag v;
while ((v = Read(ip)) != null)
list.Add(v);
return list;
@ -1039,7 +1041,7 @@ namespace Server.Commands
list.m_Params = m_EmptyParams;
}
list.m_Entries = new ArrayList();
list.m_Entries = new List<DecorationEntryMag>();
while ((line = ip.ReadLine()) != null)
{

View file

@ -214,7 +214,7 @@ namespace Server.Commands
}
}
public static void FormatGeneric(Type type, ref string typeName, ref string fileName, ref string linkName)
public static void FormatGeneric(Type type, out string typeName, out string fileName, out string linkName)
{
string name = null;
string fnam = null;
@ -274,8 +274,10 @@ namespace Server.Commands
}
}
if (name == null) typeName = type.Name;
else typeName = name;
if (name == null)
typeName = type.Name;
else
typeName = name;
if (fnam == null) fileName = "docs/types/" + SanitizeType(type.Name) + ".html";
else fileName = fnam + ".html";
@ -466,12 +468,7 @@ namespace Server.Commands
m_Declaring = type.DeclaringType;
m_Interfaces = type.GetInterfaces();
FormatGeneric(m_Type, ref m_TypeName, ref m_FileName, ref m_LinkName);
// Console.WriteLine( ">> inline typeinfo: "+m_TypeName );
// m_TypeName = GetGenericTypeName( m_Type );
// m_FileName = Docs.GetFileName( "docs/types/", GetGenericTypeName( m_Type, "-", "-" ), ".html" );
// m_Writer = Docs.GetWriter( "docs/types/", m_FileName );
FormatGeneric(m_Type, out m_TypeName, out m_FileName, out m_LinkName);
}
public string FileName => m_FileName;
@ -601,7 +598,7 @@ namespace Server.Commands
append.Append(" *");
}
}
else if (realType.IsArray)
else if (realType?.IsArray == true)
{
do
{
@ -625,30 +622,16 @@ namespace Server.Commands
string fullName = realType?.FullName ?? "(-null-)";
string aliased = null; // = realType.Name;
TypeInfo info = null;
if (realType != null)
if (realType != null && m_Types.TryGetValue(realType, out TypeInfo info))
{
m_Types.TryGetValue(realType, out info);
}
if (info != null)
{
aliased = "<!-- DBG-0 -->" + info.LinkName(null);
//aliased = String.Format( "<a href=\"{0}\">{1}</a>", info.m_FileName, info.m_TypeName );
aliased = $"<!-- DBG-0 -->{info.LinkName(null)}";
}
else
{
//FormatGeneric( );
if (realType?.IsGenericType == true)
{
string typeName = "";
string fileName = "";
string linkName = "";
FormatGeneric(realType, ref typeName, ref fileName, ref linkName);
linkName = linkName.Replace("@directory@", null);
aliased = linkName;
FormatGeneric(realType, out _, out _, out string linkName);
aliased = linkName.Replace("@directory@", null);
}
else
{
@ -768,7 +751,7 @@ namespace Server.Commands
AddIndexLink(html, "commands.html", "Commands",
"Every available command. This contains command name, usage, aliases, and description.");
AddIndexLink(html, "objects.html", "Constructible Objects",
"Every constructable item or npc. This contains object name and usage. Hover mouse over parameters to see type description.");
"Every constructible item or npc. This contains object name and usage. Hover mouse over parameters to see type description.");
AddIndexLink(html, "keywords.html", "Speech Keywords",
"Lists speech keyword numbers and associated match patterns. These are used in some scripts for multi-language matching of client speech.");
AddIndexLink(html, "bodies.html", "Body List",
@ -1861,7 +1844,8 @@ namespace Server.Commands
{
public int Compare(SpeechEntry x, SpeechEntry y)
{
return x.Index.CompareTo(y.Index);
if (x == null && y == null) return 0;
return x?.Index.CompareTo(y?.Index) ?? 1;
}
}
@ -1940,12 +1924,14 @@ namespace Server.Commands
{
public int Compare(DocCommandEntry a, DocCommandEntry b)
{
int v = b.AccessLevel.CompareTo(a.AccessLevel);
if (a == null && b == null) return 0;
int v = b?.AccessLevel.CompareTo(a?.AccessLevel) ?? 1;
if (v == 0)
v = a.Name.CompareTo(b.Name);
return v;
if (v != 0)
return v;
return a?.Name.CompareTo(b?.Name) ?? 1;
}
}
@ -2198,10 +2184,7 @@ namespace Server.Commands
private static bool IsConstructible(Type t, out bool isItem)
{
if (isItem = typeofItem.IsAssignableFrom(t))
return true;
return typeofMobile.IsAssignableFrom(t);
return (isItem = typeofItem.IsAssignableFrom(t)) || typeofMobile.IsAssignableFrom(t);
}
private static bool IsConstructible(ConstructorInfo ctor)
@ -2214,14 +2197,14 @@ namespace Server.Commands
List<TypeInfo> types = new List<TypeInfo>(m_Types.Values);
types.Sort(new TypeComparer());
ArrayList items = new ArrayList(), mobiles = new ArrayList();
List<(Type, ConstructorInfo[])> items = new List<(Type, ConstructorInfo[])>();
List<(Type, ConstructorInfo[])> mobiles = new List<(Type, ConstructorInfo[])>();
for (int i = 0; i < types.Count; ++i)
{
Type t = types[i].m_Type;
bool isItem;
if (t.IsAbstract || !IsConstructible(t, out isItem))
if (t.IsAbstract || !IsConstructible(t, out bool isItem))
continue;
ConstructorInfo[] ctors = t.GetConstructors();
@ -2232,8 +2215,7 @@ namespace Server.Commands
if (anyConstructible)
{
(isItem ? items : mobiles).Add(t);
(isItem ? items : mobiles).Add(ctors);
(isItem ? items : mobiles).Add((t, ctors));
}
}
@ -2255,8 +2237,11 @@ namespace Server.Commands
html.WriteLine(" <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">");
html.WriteLine(" <tr><td class=\"header\">Item Name</td><td class=\"header\">Usage</td></tr>");
for (int i = 0; i < items.Count; i += 2)
DocumentConstructibleObject(html, (Type)items[i], (ConstructorInfo[])items[i + 1]);
items.ForEach(tuple =>
{
var (type, constructors) = tuple;
DocumentConstructibleObject(html, type, constructors);
});
html.WriteLine(" </table></td></tr></table><br><br>");
@ -2266,8 +2251,11 @@ namespace Server.Commands
html.WriteLine(" <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">");
html.WriteLine(" <tr><td class=\"header\">Mobile Name</td><td class=\"header\">Usage</td></tr>");
for (int i = 0; i < mobiles.Count; i += 2)
DocumentConstructibleObject(html, (Type)mobiles[i], (ConstructorInfo[])mobiles[i + 1]);
mobiles.ForEach(tuple =>
{
var (type, constructors) = tuple;
DocumentConstructibleObject(html, type, constructors);
});
html.WriteLine(" </table></td></tr></table>");
@ -2513,12 +2501,8 @@ namespace Server.Commands
if (ifaceInfo == null)
{
string typeName = "";
string fileName = "";
string linkName = "";
FormatGeneric(iface, ref typeName, ref fileName, ref linkName);
linkName = linkName.Replace("@directory@", null);
typeHtml.Write("<!-- DBG-2.1 -->" + linkName);
FormatGeneric(iface, out _, out _, out string linkName);
typeHtml.Write($"<!-- DBG-2.1 -->{linkName.Replace("@directory@", null)}");
}
else
{
@ -2725,9 +2709,9 @@ namespace Server.Commands
public override bool Equals(object obj)
{
BodyEntry e = (BodyEntry)obj;
BodyEntry e = obj as BodyEntry;
return Body == e.Body && BodyType == e.BodyType && Name == e.Name;
return Body == e?.Body && BodyType == e.BodyType && Name == e.Name;
}
public override int GetHashCode()
@ -2740,15 +2724,16 @@ namespace Server.Commands
{
public int Compare(BodyEntry a, BodyEntry b)
{
int v = a.BodyType.CompareTo(b.BodyType);
if (a == null && b == null) return 0;
int v = a?.BodyType.CompareTo(b?.BodyType) ?? 1;
if (v == 0)
v = a.Body.BodyID.CompareTo(b.Body.BodyID);
v = a?.Body.BodyID.CompareTo(b?.Body.BodyID) ?? 1;
if (v == 0)
v = a.Name.CompareTo(b.Name);
return v;
if (v != 0)
return v;
return a?.Name.CompareTo(b?.Name) ?? 1;
}
}

View file

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Server.Items;
@ -16,7 +16,7 @@ namespace Server.Commands
public static void Export_OnCommand(CommandEventArgs e)
{
StreamWriter w = new StreamWriter(ExportFile);
ArrayList remove = new ArrayList();
List<Item> remove = new List<Item>();
int count = 0;
e.Mobile.SendMessage("Exporting all static items to \"{0}\"...", ExportFile);

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
@ -54,14 +54,6 @@ namespace Server.Commands
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, Encoding.UTF8);
@ -84,18 +76,18 @@ namespace Server.Commands
xml.WriteAttributeString("title", ce.Title);
ArrayList subCats = new ArrayList(ce.SubCategories);
List<CategoryEntry> subCats = new List<CategoryEntry>(ce.SubCategories);
subCats.Sort(new CategorySorter());
for (int i = 0; i < subCats.Count; ++i)
RecurseExport(xml, (CategoryEntry)subCats[i]);
RecurseExport(xml, subCats[i]);
ce.Matched.Sort(new CategorySorter());
ce.Matched.Sort(new CategoryTypeSorter());
for (int i = 0; i < ce.Matched.Count; ++i)
{
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
CategoryTypeEntry cte = ce.Matched[i];
xml.WriteStartElement("object");
@ -148,7 +140,7 @@ namespace Server.Commands
public static void Load()
{
ArrayList types = new ArrayList();
List<Type> types = new List<Type>();
AddTypes(Core.Assembly, types);
@ -159,7 +151,7 @@ namespace Server.Commands
m_RootMobiles = Load(types, "Data/mobiles.cfg");
}
private static CategoryEntry Load(ArrayList types, string config)
private static CategoryEntry Load(List<Type> types, string config)
{
CategoryLine[] lines = CategoryLine.Load(config);
@ -186,7 +178,7 @@ namespace Server.Commands
return ctor != null && ctor.IsDefined(typeofConstructible, false);
}
private static void AddTypes(Assembly asm, ArrayList types)
private static void AddTypes(Assembly asm, List<Type> types)
{
Type[] allTypes = asm.GetTypes();
@ -202,11 +194,11 @@ namespace Server.Commands
}
}
private static void Fill(CategoryEntry root, ArrayList list)
private static void Fill(CategoryEntry root, List<Type> list)
{
for (int i = 0; i < list.Count; ++i)
{
Type type = (Type)list[i];
Type type = list[i];
CategoryEntry match = GetDeepestMatch(root, type);
if (match == null)
@ -218,6 +210,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
}
@ -239,21 +232,12 @@ namespace Server.Commands
}
}
public class CategorySorter : IComparer
public class CategorySorter : IComparer<CategoryEntry>
{
public int Compare(object x, object y)
public int Compare(CategoryEntry x, CategoryEntry y)
{
string a = null, b = null;
if (x is CategoryEntry entry)
a = entry.Title;
else if (x is CategoryTypeEntry xTypeEntry)
a = xTypeEntry.Type.Name;
if (y is CategoryEntry categoryEntry)
b = categoryEntry.Title;
else if (y is CategoryTypeEntry yTypeEntry)
b = yTypeEntry.Type.Name;
string a = x?.Title;
string b = y?.Title;
if (a == null && b == null)
return 0;
@ -261,13 +245,27 @@ namespace Server.Commands
if (a == null)
return 1;
if (b == null)
return -1;
return a.CompareTo(b);
}
}
public class CategoryTypeSorter : IComparer<CategoryTypeEntry>
{
public int Compare(CategoryTypeEntry x, CategoryTypeEntry y)
{
string a = x?.Type.Name;
string b = y?.Type.Name;
if (a == null && b == null)
return 0;
if (a == null)
return 1;
return a.CompareTo(b);
}
}
public class CategoryTypeEntry
{
public CategoryTypeEntry(Type type)
@ -283,21 +281,13 @@ namespace Server.Commands
public class CategoryEntry
{
public CategoryEntry()
{
Title = "(empty)";
Matches = new Type[0];
SubCategories = new CategoryEntry[0];
Matched = new ArrayList();
}
public CategoryEntry(CategoryEntry parent, string title, CategoryEntry[] subCats)
public CategoryEntry(CategoryEntry parent = null, string title = "(empty)", CategoryEntry[] subCats = null)
{
Parent = parent;
Title = title;
SubCategories = subCats;
SubCategories = subCats ?? new CategoryEntry[0];
Matches = new Type[0];
Matched = new ArrayList();
Matched = new List<CategoryTypeEntry>();
}
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
@ -321,7 +311,7 @@ namespace Server.Commands
text = text.Substring(start, end - start);
string[] split = text.Split(';');
ArrayList list = new ArrayList();
List<Type> list = new List<Type>();
for (int i = 0; i < split.Length; ++i)
{
@ -333,20 +323,22 @@ namespace Server.Commands
list.Add(type);
}
Matches = (Type[])list.ToArray(typeof(Type));
Matches = list.ToArray();
list.Clear();
int ourIndentation = lines[index].Indentation;
++index;
List<CategoryEntry> entryList = new List<CategoryEntry>();
while (index < lines.Length && lines[index].Indentation > ourIndentation)
list.Add(new CategoryEntry(this, lines, ref index));
entryList.Add(new CategoryEntry(this, lines, ref index));
SubCategories = (CategoryEntry[])list.ToArray(typeof(CategoryEntry));
list.Clear();
SubCategories = entryList.ToArray();
entryList.Clear();
Matched = list;
Matched = new List<CategoryTypeEntry>();
}
public string Title{ get; }
@ -357,7 +349,7 @@ namespace Server.Commands
public CategoryEntry[] SubCategories{ get; }
public ArrayList Matched{ get; }
public List<CategoryTypeEntry> Matched{ get; }
public bool IsMatch(Type type)
{
@ -393,7 +385,7 @@ namespace Server.Commands
public static CategoryLine[] Load(string path)
{
ArrayList list = new ArrayList();
List<CategoryLine> list = new List<CategoryLine>();
if (File.Exists(path))
using (StreamReader ip = new StreamReader(path))
@ -404,7 +396,7 @@ namespace Server.Commands
list.Add(new CategoryLine(line));
}
return (CategoryLine[])list.ToArray(typeof(CategoryLine));
return list.ToArray();
}
}
}

View file

@ -1,5 +1,4 @@
using System.Collections;
using Server.Gumps;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
@ -13,13 +12,8 @@ namespace Server.Commands.Generic
public abstract class BaseCommand
{
private ArrayList m_Responses, m_Failures;
public BaseCommand()
{
m_Responses = new ArrayList();
m_Failures = new ArrayList();
}
private List<MessageEntry> m_Responses = new List<MessageEntry>();
private List<MessageEntry> m_Failures = new List<MessageEntry>();
public bool ListOptimized{ get; set; }
@ -50,7 +44,7 @@ namespace Server.Commands.Generic
return mob == null || mob == from || from.AccessLevel > mob.AccessLevel;
}
public virtual void ExecuteList(CommandEventArgs e, ArrayList list)
public virtual void ExecuteList(CommandEventArgs e, List<object> list)
{
for (int i = 0; i < list.Count; ++i)
Execute(e, list[i]);
@ -69,7 +63,7 @@ namespace Server.Commands.Generic
{
for (int i = 0; i < m_Responses.Count; ++i)
{
MessageEntry entry = (MessageEntry)m_Responses[i];
MessageEntry entry = m_Responses[i];
if (entry.m_Message == message)
{
@ -84,16 +78,11 @@ namespace Server.Commands.Generic
m_Responses.Add(new MessageEntry(message));
}
public void AddResponse(Gump gump)
{
m_Responses.Add(gump);
}
public void LogFailure(string message)
{
for (int i = 0; i < m_Failures.Count; ++i)
{
MessageEntry entry = (MessageEntry)m_Failures[i];
MessageEntry entry = m_Failures[i];
if (entry.m_Message == message)
{
@ -113,23 +102,16 @@ namespace Server.Commands.Generic
if (m_Responses.Count > 0)
for (int i = 0; i < m_Responses.Count; ++i)
{
object obj = m_Responses[i];
MessageEntry entry = m_Responses[i];
if (obj is MessageEntry entry)
{
from.SendMessage(entry.ToString());
from.SendMessage(entry.ToString());
if (flushToLog)
CommandLogging.WriteLine(from, entry.ToString());
}
else if (obj is Gump gump)
{
from.SendGump(gump);
}
if (flushToLog)
CommandLogging.WriteLine(from, entry.ToString());
}
else
for (int i = 0; i < m_Failures.Count; ++i)
from.SendMessage(((MessageEntry)m_Failures[i]).ToString());
from.SendMessage(m_Failures[i].ToString());
m_Responses.Clear();
m_Failures.Clear();
@ -148,10 +130,7 @@ namespace Server.Commands.Generic
public override string ToString()
{
if (m_Count > 1)
return $"{m_Message} ({m_Count})";
return m_Message;
return m_Count > 1 ? $"{m_Message} ({m_Count})" : m_Message;
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Accounting;
using Server.Engines.Help;
@ -91,7 +90,7 @@ namespace Server.Commands.Generic
ListOptimized = true;
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
try
{
@ -184,7 +183,7 @@ namespace Server.Commands.Generic
ListOptimized = true;
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (list.Count == 1)
AddResponse("There is one matching object.");
@ -205,13 +204,8 @@ namespace Server.Commands.Generic
Description = "Opens the web browser of a targeted player to a specified url.";
}
public static void OpenBrowser_Callback(Mobile from, bool okay, object state)
public static void OpenBrowser_Callback(Mobile from, bool okay, Mobile gm, string url, bool echo)
{
object[] states = (object[])state;
Mobile gm = (Mobile)states[0];
string url = (string)states[1];
bool echo = (bool)states[2];
if (okay)
{
if (echo)
@ -257,7 +251,7 @@ namespace Server.Commands.Generic
mob.SendGump(new WarningGump(1060637, 30720,
$"A game master is requesting to open your web browser to the following URL:<br>{url}", 0xFFC000,
320, 240, OpenBrowser_Callback, new object[] { from, url, echo }));
320, 240, okay => OpenBrowser_Callback(mob, okay, from, url, echo)));
}
}
else
@ -276,7 +270,7 @@ namespace Server.Commands.Generic
Execute(e, obj, true);
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
for (int i = 0; i < list.Count; ++i)
Execute(e, list[i], false);
@ -406,7 +400,7 @@ namespace Server.Commands.Generic
"Adds an item by name to the backpack of a targeted player or npc, or a targeted container. Optional constructor parameters. Optional set property list.";
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (e.Arguments.Length == 0)
return;
@ -763,12 +757,8 @@ namespace Server.Commands.Generic
Description = "Deletes a targeted item or mobile. Does not delete players.";
}
private void OnConfirmCallback(Mobile from, bool okay, object state)
private void OnConfirmCallback(Mobile from, bool okay, CommandEventArgs e, List<object> list)
{
object[] states = (object[])state;
CommandEventArgs e = (CommandEventArgs)states[0];
ArrayList list = (ArrayList)states[1];
bool flushToLog = false;
if (okay)
@ -798,13 +788,14 @@ namespace Server.Commands.Generic
Flush(from, flushToLog);
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (list.Count > 1)
{
e.Mobile.SendGump(new WarningGump(1060637, 30720,
Mobile from = e.Mobile;
from.SendGump(new WarningGump(1060637, 30720,
$"You are about to delete {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list }));
0xFFC000, 420, 280, okay => OnConfirmCallback(from, okay, e, list)));
AddResponse("Awaiting confirmation...");
}
else

View file

@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
using Server.Items;
@ -103,8 +102,7 @@ namespace Server.Commands.Generic
protected override void OnTarget(Mobile from, object obj)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out house);
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out HouseFoundation house);
switch (result)
{
@ -142,21 +140,17 @@ namespace Server.Commands.Generic
#region Area targeting mode
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
e.Mobile.SendGump(new WarningGump(1060637, 30720,
Mobile from = e.Mobile;
from.SendGump(new WarningGump(1060637, 30720,
$"You are about to insert {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list, e.Length < 1 || !e.GetBoolean(0) }));
0xFFC000, 420, 280, okay => OnConfirmCallback(from, okay, list, e.Length < 1 || !e.GetBoolean(0))));
AddResponse("Awaiting confirmation...");
}
private void OnConfirmCallback(Mobile from, bool okay, object state)
private void OnConfirmCallback(Mobile from, bool okay, List<object> list, bool staticsOnly)
{
object[] states = (object[])state;
CommandEventArgs e = (CommandEventArgs)states[0];
ArrayList list = (ArrayList)states[1];
bool staticsOnly = (bool)states[2];
bool flushToLog = false;
if (okay)
@ -166,8 +160,7 @@ namespace Server.Commands.Generic
for (int i = 0; i < list.Count; ++i)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out HouseFoundation house);
switch (result)
{

View file

@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Server.Gumps;
@ -20,13 +19,12 @@ namespace Server.Commands.Generic
ListOptimized = true;
}
public override void ExecuteList(CommandEventArgs e, ArrayList list)
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (list.Count > 0)
{
List<string> columns = new List<string>();
List<string> columns = new List<string> { "Object" };
columns.Add("Object");
if (e.Length > 0)
{
@ -55,12 +53,12 @@ namespace Server.Commands.Generic
private string[] m_Columns;
private Mobile m_From;
private ArrayList m_List;
private List<object> m_List;
private int m_Page;
private object m_Select;
public InterfaceGump(Mobile from, string[] columns, ArrayList list, int page, object select) : base(30, 30)
public InterfaceGump(Mobile from, string[] columns, List<object> list, int page, object select) : base(30, 30)
{
m_From = from;
@ -222,7 +220,7 @@ namespace Server.Commands.Generic
if (!BaseCommand.IsAccessible(m_From, obj))
{
m_From.SendMessage("That is not accessible.");
m_From.SendLocalizedMessage(500447); // That is not accessible.
m_From.SendGump(new InterfaceGump(m_From, m_Columns, m_List, m_Page, m_Select));
break;
}
@ -248,10 +246,10 @@ namespace Server.Commands.Generic
private Item m_Item;
private ArrayList m_List;
private List<object> m_List;
private int m_Page;
public InterfaceItemGump(Mobile from, string[] columns, ArrayList list, int page, Item item) : base(30, 30)
public InterfaceItemGump(Mobile from, string[] columns, List<object> list, int page, Item item) : base(30, 30)
{
m_From = from;
@ -381,12 +379,12 @@ namespace Server.Commands.Generic
private string[] m_Columns;
private Mobile m_From;
private ArrayList m_List;
private List<object> m_List;
private Mobile m_Mobile;
private int m_Page;
public InterfaceMobileGump(Mobile from, string[] columns, ArrayList list, int page, Mobile mob)
public InterfaceMobileGump(Mobile from, string[] columns, List<object> list, int page, Mobile mob)
: base(30, 30)
{
m_From = from;

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
@ -48,7 +47,7 @@ namespace Server.Commands.Generic
return true;
}
public void Filter(ArrayList list)
public void Filter(List<object> list)
{
for (int i = 0; i < Count; ++i)
this[i].Filter(list);
@ -127,7 +126,7 @@ namespace Server.Commands.Generic
return true;
}
public virtual void Filter(ArrayList list)
public virtual void Filter(List<object> list)
{
}
}

View file

@ -109,8 +109,8 @@ namespace Server.Commands.Generic
}
else
{
MethodInfo parseMethod = null;
object[] parseArgs = null;
MethodInfo parseMethod;
object[] parseArgs;
MethodInfo parseNumber = Type.GetMethod(
"Parse",

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
@ -8,7 +7,7 @@ namespace Server.Commands.Generic
{
public static class DistinctCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props)
public static IComparer<T> Compile<T>(AssemblyEmitter assembly, Type objectType, Property[] props)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__distinct",
@ -29,7 +28,8 @@ namespace Server.Commands.Generic
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Call, typeof(T).GetConstructor(Type.EmptyTypes) ??
throw new Exception($"Could not find empty constructor for type {typeof(T).FullName}"));
// return;
il.Emit(OpCodes.Ret);
@ -39,7 +39,7 @@ namespace Server.Commands.Generic
#region IComparer
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
typeBuilder.AddInterfaceImplementation(typeof(IComparer<T>));
MethodBuilder compareMethod;
@ -52,7 +52,7 @@ namespace Server.Commands.Generic
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object), typeof(object) });
/* params */ new[] { typeof(T), typeof(T) });
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
@ -105,14 +105,14 @@ namespace Server.Commands.Generic
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
typeof(IComparer<T>).GetMethod(
"Compare",
new[]
{
typeof(object),
typeof(object)
typeof(T),
typeof(T)
}
)
) ?? throw new Exception($"No Compare method found for type {typeof(T).FullName}")
);
compareMethod = emitter.Method;
@ -124,7 +124,7 @@ namespace Server.Commands.Generic
#region IEqualityComparer
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<T>));
#region Equals
@ -135,7 +135,7 @@ namespace Server.Commands.Generic
/* name */ "Equals",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(bool),
/* params */ new[] { typeof(object), typeof(object) });
/* params */ new[] { typeof(T), typeof(T) });
emitter.Generator.Emit(OpCodes.Ldarg_0);
emitter.Generator.Emit(OpCodes.Ldarg_1);
@ -151,14 +151,14 @@ namespace Server.Commands.Generic
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
typeof(IEqualityComparer<T>).GetMethod(
"Equals",
new[]
{
typeof(object),
typeof(object)
typeof(T),
typeof(T)
}
)
) ?? throw new Exception($"No Equals method found for type {typeof(T).FullName}")
);
}
@ -173,7 +173,7 @@ namespace Server.Commands.Generic
/* name */ "GetHashCode",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object) });
/* params */ new[] { typeof(T) });
LocalBuilder obj = emitter.CreateLocal(objectType);
@ -193,7 +193,7 @@ namespace Server.Commands.Generic
MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);
if (getHashCode == null)
getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);
getHashCode = typeof(T).GetMethod("GetHashCode", Type.EmptyTypes);
if (active != typeof(int))
{
@ -237,13 +237,13 @@ namespace Server.Commands.Generic
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
typeof(IEqualityComparer<T>).GetMethod(
"GetHashCode",
new[]
{
typeof(object)
typeof(T)
}
)
) ?? throw new Exception($"No GetHashCode method found for type {typeof(T).FullName}")
);
}
@ -253,7 +253,7 @@ namespace Server.Commands.Generic
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
return (IComparer<T>)Activator.CreateInstance(comparerType);
}
}
}

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
@ -45,12 +45,12 @@ namespace Server.Commands.Generic
public static class SortCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
public static IComparer<T> Compile<T>(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__sort",
TypeAttributes.Public,
typeof(object)
typeof(T)
);
#region Constructor
@ -66,7 +66,8 @@ namespace Server.Commands.Generic
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Call, typeof(T).GetConstructor(Type.EmptyTypes) ??
throw new Exception($"Could not find empty constructor for type {typeof(T).FullName}"));
// return;
il.Emit(OpCodes.Ret);
@ -76,12 +77,9 @@ namespace Server.Commands.Generic
#region IComparer
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
MethodBuilder compareMethod;
typeBuilder.AddInterfaceImplementation(typeof(IComparer<T>));
#region Compare
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
@ -89,7 +87,7 @@ namespace Server.Commands.Generic
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object), typeof(object) });
/* params */ new[] { typeof(T), typeof(T) });
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
@ -145,17 +143,15 @@ namespace Server.Commands.Generic
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
typeof(IComparer<T>).GetMethod(
"Compare",
new[]
{
typeof(object),
typeof(object)
typeof(T),
typeof(T)
}
)
) ?? throw new Exception($"No Compare method found for type {typeof(T).FullName}")
);
compareMethod = emitter.Method;
}
#endregion
@ -163,8 +159,7 @@ namespace Server.Commands.Generic
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
return (IComparer<T>)Activator.CreateInstance(comparerType);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
@ -9,7 +8,7 @@ namespace Server.Commands.Generic
public static ExtensionInfo ExtInfo =
new ExtensionInfo(30, "Distinct", -1, delegate { return new DistinctExtension(); });
private IComparer m_Comparer;
private IComparer<object> m_Comparer;
private List<Property> m_Properties;
@ -39,7 +38,7 @@ namespace Server.Commands.Generic
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray());
m_Comparer = DistinctCompiler.Compile<object>(assembly, baseType, m_Properties.ToArray());
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
@ -57,12 +56,12 @@ namespace Server.Commands.Generic
}
}
public override void Filter(ArrayList list)
public override void Filter(List<object> list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
ArrayList copy = new ArrayList(list);
List<object> copy = new List<object>(list);
copy.Sort(m_Comparer);

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
@ -24,7 +24,7 @@ namespace Server.Commands.Generic
throw new Exception("Limit cannot be less than zero.");
}
public override void Filter(ArrayList list)
public override void Filter(List<object> list)
{
if (list.Count > Limit)
list.RemoveRange(Limit, list.Count - Limit);

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
@ -8,7 +7,7 @@ namespace Server.Commands.Generic
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(40, "Order", -1, () => new SortExtension());
private IComparer m_Comparer;
private IComparer<object> m_Comparer;
private List<OrderInfo> m_Orders;
@ -38,7 +37,7 @@ namespace Server.Commands.Generic
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = SortCompiler.Compile(assembly, baseType, m_Orders.ToArray());
m_Comparer = SortCompiler.Compile<object>(assembly, baseType, m_Orders.ToArray());
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
@ -93,7 +92,7 @@ namespace Server.Commands.Generic
}
}
public override void Filter(ArrayList list)
public override void Filter(List<object> list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
@ -22,24 +22,18 @@ namespace Server.Commands.Generic
public override void Process(Mobile from, BaseCommand command, string[] args)
{
BoundingBoxPicker.Begin(from, OnTarget, new object[] { command, args });
BoundingBoxPicker.Begin(from, (map, start, end) => OnTarget(from, map, start, end, command, args));
}
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, object state)
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, BaseCommand command, string[] args)
{
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 (!CheckObjectTypes(from, command, ext, out items, out mobiles))
if (!CheckObjectTypes(from, command, ext, out bool items, out bool mobiles))
return;
IPooledEnumerable<IEntity> eable;
@ -49,7 +43,9 @@ namespace Server.Commands.Generic
else
return;
ArrayList objs = new ArrayList();
eable.Free();
List<object> objs = new List<object>();
foreach (IEntity obj in eable)
{

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
@ -212,7 +211,7 @@ namespace Server.Commands.Generic
bool flushToLog = false;
if (obj is ArrayList list)
if (obj is List<object> list)
{
if (list.Count > 20)
CommandLogging.Enabled = false;
@ -230,7 +229,7 @@ namespace Server.Commands.Generic
else if (obj != null)
{
if (command.ListOptimized)
command.ExecuteList(e, new ArrayList { obj });
command.ExecuteList(e, new List<object>{ obj });
else
command.Execute(e, obj);
}

View file

@ -1,7 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Server.Items;
using Server.Targeting;
@ -23,21 +21,17 @@ namespace Server.Commands.Generic
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
(m, targeted) => OnTarget(m, targeted, command, args));
}
public void OnTarget(Mobile from, object targeted, object state)
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
from.SendLocalizedMessage(500447); // 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
@ -60,10 +54,15 @@ namespace Server.Commands.Generic
return;
}
List<Item> list = cont.FindItemsByType<Item>().Where(item => ext.IsValid(item)).ToList();
List<object> list = new List<object>();
// TODO: Is there a way to avoid using ArrayList?
ext.Filter(new ArrayList(list));
foreach (Item item in cont.FindItemsByType<Item>())
{
if (ext.IsValid(item))
list.Add(item);
}
ext.Filter(list);
RunCommand(from, list, command, args);
}

View file

@ -25,8 +25,7 @@ namespace Server.Commands.Generic
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 });
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0), command, args);
}
}
}

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
@ -22,12 +22,10 @@ namespace Server.Commands.Generic
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
if (!CheckObjectTypes(from, command, ext, out bool items, out bool mobiles))
return;
ArrayList list = new ArrayList();
List<object> list = new List<object>();
if (items)
foreach (Item item in World.Items.Values)

View file

@ -1,6 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using Server.Network;
namespace Server.Commands.Generic
@ -24,9 +24,7 @@ namespace Server.Commands.Generic
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
return;
if (!mobiles) // sanity check
@ -35,8 +33,8 @@ namespace Server.Commands.Generic
return;
}
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
List<object> list = new List<object>();
List<IPAddress> addresses = new List<IPAddress>();
List<NetState> states = NetState.Instances;

View file

@ -17,20 +17,16 @@ namespace Server.Commands.Generic
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
(m, targeted) => OnTarget(m, targeted, command, args));
}
public void OnTarget(Mobile from, object targeted, object state)
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
{
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.SendLocalizedMessage(500447); // That is not accessible.
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
(m, t) => OnTarget(m, t, command, args));
return;
}
@ -38,7 +34,7 @@ namespace Server.Commands.Generic
{
case ObjectTypes.Both:
{
if (!(targeted is Item) && !(targeted is Mobile))
if (!(targeted is Item || targeted is Mobile))
{
from.SendMessage("This command does not work on that.");
return;
@ -70,8 +66,8 @@ namespace Server.Commands.Generic
RunCommand(from, targeted, command, args);
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget),
new object[] { command, args });
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
(m, t) => OnTarget(m, t, command, args));
}
}
}

View file

@ -81,7 +81,7 @@ namespace Server.Commands.Generic
break;
}
return ParseDirect(from, conditionArgs, 0, conditionArgs.Length);
return ParseDirect(from, conditionArgs, 0, conditionArgs?.Length ?? 0);
}
public static ObjectConditional ParseDirect(Mobile from, string[] args, int offset, int size)

View file

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Network;
@ -24,9 +23,7 @@ namespace Server.Commands.Generic
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
return;
if (!mobiles) // sanity check
@ -35,7 +32,7 @@ namespace Server.Commands.Generic
return;
}
ArrayList list = new ArrayList();
List<object> list = new List<object>();
List<NetState> states = NetState.Instances;

View file

@ -73,7 +73,7 @@ namespace Server.Commands.Generic
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 });
impl.OnTarget(from, map, start, end, command, args);
}
}
}

View file

@ -1,5 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
@ -22,14 +22,12 @@ namespace Server.Commands.Generic
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
return;
Region reg = from.Region;
ArrayList list = new ArrayList();
List<object> list = new List<object>();
if (mobiles)
{

View file

@ -15,7 +15,7 @@ namespace Server.Commands.Generic
{
if (e.Length >= 2)
{
Serial serial = e.GetInt32(0);
Serial serial = e.GetUInt32(0);
object obj = null;

View file

@ -38,21 +38,17 @@ namespace Server.Commands.Generic
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
(m, targeted) => OnTarget(m, targeted, command, args));
}
public void OnTarget(Mobile from, object targeted, object state)
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
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:

View file

@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server.Commands.Generic;
@ -185,12 +184,10 @@ namespace Server.Commands
}
}
public static void DeleteList_Callback(Mobile from, bool okay, object state)
public static void DeleteList_Callback(Mobile from, bool okay, List<IEntity> list)
{
if (okay)
{
List<IEntity> list = (List<IEntity>)state;
CommandLogging.WriteLine(from, "{0} {1} deleting {2} object{3}", from.AccessLevel,
CommandLogging.Format(from), list.Count, list.Count == 1 ? "" : "s");
@ -213,11 +210,12 @@ namespace Server.Commands
[Description("Deletes all items and mobiles in your facet. Players and their inventory will not be deleted.")]
public static void ClearFacet_OnCommand(CommandEventArgs e)
{
Map map = e.Mobile.Map;
Mobile from = e.Mobile;
Map map = from.Map;
if (map == null || map == Map.Internal)
{
e.Mobile.SendMessage("You may not run that command here.");
from.SendMessage("You may not run that command here.");
return;
}
@ -233,17 +231,17 @@ namespace Server.Commands
if (list.Count > 0)
{
CommandLogging.WriteLine(e.Mobile, "{0} {1} starting facet clear of {2} ({3} object{4})",
e.Mobile.AccessLevel, CommandLogging.Format(e.Mobile), map, list.Count, list.Count == 1 ? "" : "s");
CommandLogging.WriteLine(from, "{0} {1} starting facet clear of {2} ({3} object{4})",
from.AccessLevel, CommandLogging.Format(from), map, list.Count, list.Count == 1 ? "" : "s");
e.Mobile.SendGump(
from.SendGump(
new WarningGump(1060635, 30720,
$"You are about to delete {list.Count} object{(list.Count == 1 ? "" : "s")} from this facet. Do you really wish to continue?",
0xFFC000, 360, 260, DeleteList_Callback, list));
0xFFC000, 360, 260, okay => DeleteList_Callback(from, okay, list)));
}
else
{
e.Mobile.SendMessage("There were no objects found to delete.");
from.SendMessage("There were no objects found to delete.");
}
}
@ -285,7 +283,7 @@ namespace Server.Commands
}
else if (obj is Mobile master && master.Player)
{
ArrayList pets = new ArrayList();
List<BaseCreature> pets = new List<BaseCreature>();
foreach (Mobile m in World.Mobiles.Values)
if (m is BaseCreature bc)
@ -443,7 +441,7 @@ namespace Server.Commands
{
try
{
int ser = e.GetInt32(0);
uint ser = e.GetUInt32(0);
IEntity ent = World.FindEntity(ser);
@ -567,6 +565,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
from.SendMessage("Region name not found");
@ -760,7 +759,7 @@ namespace Server.Commands
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
from.SendLocalizedMessage(500447); // That is not accessible.
return;
}

View file

@ -243,7 +243,6 @@ namespace Server.Commands
m_List = list;
}
AddNewPage();
if (m_Page > 0)
@ -269,7 +268,6 @@ namespace Server.Commands
if ((int)c.AccessLevel != last)
{
AddNewLine();
AddEntryHtml(20 + OffsetSize + 160, Color(c.AccessLevel.ToString(), 0xFF0000));
AddEntryHeader(20);
line++;
@ -278,9 +276,7 @@ namespace Server.Commands
last = (int)c.AccessLevel;
AddNewLine();
AddEntryHtml(20 + OffsetSize + 160, c.Name);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight);
}
}
@ -295,7 +291,7 @@ namespace Server.Commands
{
case 0:
{
m.CloseGump(typeof(CommandInfoGump));
m.CloseGump<CommandInfoGump>();
break;
}
case 1:

View file

@ -36,6 +36,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -87,6 +88,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}

View file

@ -1,6 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Server.Diagnostics;
namespace Server.Commands
@ -52,6 +54,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -80,6 +83,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -89,37 +93,32 @@ namespace Server.Commands
{
using (StreamWriter op = new StreamWriter("objects.log"))
{
Hashtable table = new Hashtable();
Dictionary<Type, int> table = new Dictionary<Type, int>();
foreach (Item item in World.Items.Values)
{
Type type = item.GetType();
object o = table[type];
if (o == null)
table[type] = 1;
if (table.ContainsKey(type))
table[type] = 1 + table[type];
else
table[type] = 1 + (int)o;
table[type] = 1;
}
ArrayList items = new ArrayList(table);
List<KeyValuePair<Type, int>> items = table.ToList();
table.Clear();
foreach (Mobile m in World.Mobiles.Values)
{
Type type = m.GetType();
object o = table[type];
if (o == null)
table[type] = 1;
if (table.ContainsKey(type))
table[type] = 1 + table[type];
else
table[type] = 1 + (int)o;
table[type] = 1;
}
ArrayList mobiles = new ArrayList(table);
List<KeyValuePair<Type, int>> mobiles = table.ToList();
items.Sort(new CountSorter());
mobiles.Sort(new CountSorter());
@ -130,16 +129,16 @@ namespace Server.Commands
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);
items.ForEach(kvp =>
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / World.Items.Count, kvp.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);
mobiles.ForEach(kvp =>
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / World.Mobiles.Count, kvp.Key));
}
e.Mobile.SendMessage("Object table has been generated. See the file : <runuo root>/objects.log");
@ -149,7 +148,7 @@ namespace Server.Commands
[Description("Generates a log file describing all items using expanded memory.")]
public static void TraceExpanded_OnCommand(CommandEventArgs e)
{
Hashtable typeTable = new Hashtable();
Dictionary<Type, int[]> typeTable = new Dictionary<Type, int[]>();
foreach (Item item in World.Items.Values)
{
@ -162,8 +161,10 @@ namespace Server.Commands
do
{
if (!(typeTable[itemType] is int[] countTable))
typeTable[itemType] = countTable = new int[9];
typeTable.TryGetValue(itemType, out int[] countTable);
if (countTable == null)
countTable = new int[9];
if ((flags & ExpandFlag.Name) != 0)
++countTable[0];
@ -213,16 +214,15 @@ namespace Server.Commands
"Spawner"
};
ArrayList list = new ArrayList(typeTable);
List<KeyValuePair<Type, int[]>> list = typeTable.ToList();
list.Sort(new CountSorter());
list.Sort(new CountsSorter());
foreach (DictionaryEntry de in list)
foreach (KeyValuePair<Type, int[]> kvp in list)
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
int[] countTable = kvp.Value;
op.WriteLine("# {0}", itemType.FullName);
op.WriteLine("# {0}", kvp.Key.FullName);
for (int i = 0; i < countTable.Length; ++i)
if (countTable[i] > 0)
@ -234,6 +234,7 @@ namespace Server.Commands
}
catch
{
// ignored
}
}
@ -242,7 +243,7 @@ namespace Server.Commands
public static void TraceInternal_OnCommand(CommandEventArgs e)
{
int totalCount = 0;
Hashtable table = new Hashtable();
Dictionary<Type, int[]> table = new Dictionary<Type, int[]>();
foreach (Item item in World.Items.Values)
{
@ -252,7 +253,7 @@ namespace Server.Commands
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
int[] parms = table[type];
if (parms == null)
table[type] = parms = new[] { 0, 0 };
@ -269,12 +270,11 @@ namespace Server.Commands
op.WriteLine();
op.WriteLine("Type\t\tCount\t\tAmount\t\tAvg. Amount");
foreach (DictionaryEntry de in table)
foreach (KeyValuePair<Type, int[]> de in table)
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
int[] parms = 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]);
op.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3:F2}", de.Key.Name, parms[0], parms[1], (double)parms[1] / parms[0]);
}
}
}
@ -291,7 +291,7 @@ namespace Server.Commands
{
try
{
ArrayList types = new ArrayList();
List<Type> types = new List<Type>();
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.tdb", type),
FileMode.Open, FileAccess.Read, FileShare.Read)))
@ -304,7 +304,7 @@ namespace Server.Commands
long total = 0;
Hashtable table = new Hashtable();
Dictionary<Type, int> table = new Dictionary<Type, int>();
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.idx", type),
FileMode.Open, FileAccess.Read, FileShare.Read)))
@ -317,16 +317,14 @@ namespace Server.Commands
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
Type objType = types[typeID];
while (objType != null && objType != typeof(object))
while (objType != typeof(object))
{
object obj = table[objType];
if (obj == null)
table[objType] = length;
if (table.ContainsKey(objType))
table[objType] = length + table[objType];
else
table[objType] = length + (int)obj;
table[objType] = length;
objType = objType.BaseType;
total += length;
@ -334,7 +332,7 @@ namespace Server.Commands
}
}
ArrayList list = new ArrayList(table);
List<KeyValuePair<Type, int>> list = table.ToList();
list.Sort(new CountSorter());
@ -345,55 +343,46 @@ namespace Server.Commands
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);
list.ForEach(kvp =>
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / total, kvp.Key));
}
}
catch
{
// ignored
}
}
private class CountSorter : IComparer
private class CountSorter : IComparer<KeyValuePair<Type, int>>
{
public int Compare(object x, object y)
public int Compare(KeyValuePair<Type, int> x, KeyValuePair<Type, int> y)
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = GetCount(a.Value);
int bCount = GetCount(b.Value);
int aCount = x.Value;
int bCount = y.Value;
int v = -aCount.CompareTo(bCount);
if (v == 0)
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
if (v != 0)
return v;
v = aType.FullName.CompareTo(bType.FullName);
}
return v;
return x.Key.FullName.CompareTo(y.Key.FullName);
}
}
private int GetCount(object obj)
private class CountsSorter : IComparer<KeyValuePair<Type, int[]>>
{
public int Compare(KeyValuePair<Type, int[]> x, KeyValuePair<Type, int[]> y)
{
if (obj is int intObj)
return intObj;
int aCount = x.Value.Aggregate(0, (t, val) => t + val);
int bCount = y.Value.Aggregate(0, (t, val) => t + val);
if (obj is int[] list)
{
int total = 0;
int v = -aCount.CompareTo(bCount);
for (int i = 0; i < list.Length; ++i)
total += list[i];
if (v != 0)
return v;
return total;
}
return 0;
return x.Key.FullName.CompareTo(y.Key.FullName);
}
}
}
}
}

View file

@ -8,6 +8,7 @@ using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands
{
[Flags]
public enum PropertyAccess
{
Read = 0x01,
@ -54,12 +55,12 @@ namespace Server.Commands
{
if (e.Length == 1)
{
IEntity ent = World.FindEntity(e.GetInt32(0));
IEntity ent = World.FindEntity(e.GetUInt32(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.");
e.Mobile.SendLocalizedMessage(500447); // That is not accessible.
else
e.Mobile.SendGump(new PropertiesGump(e.Mobile, ent));
}
@ -394,7 +395,7 @@ namespace Server.Commands
m_ParseParams[0] = value;
return method.Invoke(o, m_ParseParams);
return method?.Invoke(o, m_ParseParams);
}
private static bool IsNumeric(Type t)
@ -465,7 +466,7 @@ namespace Server.Commands
}
if (isSerial) // mutate back
toSet = (Serial)(int)toSet;
toSet = (Serial)(toSet ?? Serial.MinusOne);
constructed = toSet;
return null;
@ -549,7 +550,7 @@ namespace Server.Commands
protected override void OnTarget(Mobile from, object o)
{
if (!BaseCommand.IsAccessible(from, o))
from.SendMessage("That is not accessible.");
from.SendLocalizedMessage(500447); // That is not accessible.
else
from.SendGump(new PropertiesGump(from, o));
}

View file

@ -22,8 +22,7 @@ namespace Server.Commands
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
if (Enum.TryParse(arg.GetString(0), true, out SkillName skill))
arg.Mobile.Target = new SkillTarget(skill, arg.GetDouble(1));
else
arg.Mobile.SendLocalizedMessage(1005631); // You have specified an invalid skill to set.
@ -50,8 +49,7 @@ namespace Server.Commands
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
if (Enum.TryParse(arg.GetString(0), true, out SkillName skill))
arg.Mobile.Target = new SkillTarget(skill);
else
arg.Mobile.SendMessage("You have specified an invalid skill to get.");

View file

@ -46,21 +46,25 @@ namespace Server
CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand);
}
public delegate void FreezeCallback( Mobile from, bool okay, StateInfo si );
[Usage("Freeze")]
[Description("Makes a targeted area of dynamic items static.")]
public static void Freeze_OnCommand(CommandEventArgs e)
{
BoundingBoxPicker.Begin(e.Mobile, FreezeBox_Callback, null);
Mobile from = e.Mobile;
BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end));
}
[Usage("FreezeMap")]
[Description("Makes every dynamic item in your map static.")]
public static void FreezeMap_OnCommand(CommandEventArgs e)
{
Map map = e.Mobile.Map;
Mobile from = e.Mobile;
Map map = from.Map;
if (map != null && map != Map.Internal)
SendWarning(e.Mobile, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D,
SendWarning(from, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D,
NullP3D, FreezeWarning_Callback);
}
@ -73,31 +77,29 @@ namespace Server
}
public static void SendWarning(Mobile m, string header, string baseWarning, Map map, Point3D start, Point3D end,
WarningGumpCallback callback)
FreezeCallback callback)
{
m.SendGump(new WarningGump(1060635, 30720, string.Format(baseWarning, string.Format(header, map)), 0xFFC000, 420,
400, callback, new StateInfo(map, start, end)));
400, okay => callback(m, okay, new StateInfo(map, start, end))));
}
private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end)
{
SendWarning(from, "You are about to freeze a section of items.", BaseFreezeWarning, map, start, end,
FreezeWarning_Callback);
}
private static void FreezeWarning_Callback(Mobile from, bool okay, object state)
private static void FreezeWarning_Callback(Mobile from, bool okay, StateInfo si)
{
if (!okay)
return;
StateInfo si = (StateInfo)state;
Freeze(from, si.m_Map, si.m_Start, si.m_End);
}
public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d)
{
Hashtable mapTable = new Hashtable();
Dictionary<Map, Dictionary<Point2D, DeltaState>> mapTable = new Dictionary<Map, Dictionary<Point2D, DeltaState>>();
if (start3d == NullP3D && end3d == NullP3D)
{
@ -123,14 +125,14 @@ namespace Server
if (itemMap == null || itemMap == Map.Internal)
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
Dictionary<Point2D, DeltaState> table = mapTable[itemMap];
if (table == null)
mapTable[itemMap] = table = new Hashtable();
mapTable[itemMap] = table = new Dictionary<Point2D, DeltaState>();
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
DeltaState state = (DeltaState)table[p];
DeltaState state = table[p];
if (state == null)
table[p] = state = new DeltaState(p);
@ -157,14 +159,14 @@ namespace Server
if (itemMap == null || itemMap == Map.Internal)
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
Dictionary<Point2D, DeltaState> table = mapTable[itemMap];
if (table == null)
mapTable[itemMap] = table = new Hashtable();
mapTable[itemMap] = table = new Dictionary<Point2D, DeltaState>();
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
DeltaState state = (DeltaState)table[p];
DeltaState state = table[p];
if (state == null)
table[p] = state = new DeltaState(p);
@ -179,7 +181,7 @@ namespace Server
{
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));
0xFFC000, 320, 240));
return;
}
@ -187,10 +189,10 @@ namespace Server
int totalFrozen = 0;
foreach (DictionaryEntry de in mapTable)
foreach (KeyValuePair<Map, Dictionary<Point2D, DeltaState>> de in mapTable)
{
Map map = (Map)de.Key;
Hashtable table = (Hashtable)de.Value;
Map map = de.Key;
Dictionary<Point2D, DeltaState> table = de.Value;
TileMatrix matrix = map.Tiles;
@ -211,9 +213,8 @@ namespace Server
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);
matrix.BlockWidth, matrix.BlockHeight, out int oldTileCount);
if (oldTileCount < 0)
continue;
@ -296,18 +297,19 @@ namespace Server
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));
0xFFC000, 320, 240));
else
from.SendGump(new NoticeGump(1060637, 30720,
$"Freeze operation completed successfully.<br><br>{totalFrozen} item{(totalFrozen != 1 ? "s were" : " was")} frozen.<br><br>You must restart your client and update it's data files to see the changes.",
0xFFC000, 320, 240, null, null));
0xFFC000, 320, 240));
}
[Usage("Unfreeze")]
[Description("Makes a targeted area of static items dynamic.")]
public static void Unfreeze_OnCommand(CommandEventArgs e)
{
BoundingBoxPicker.Begin(e.Mobile, UnfreezeBox_Callback, null);
Mobile from = e.Mobile;
BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end));
}
[Usage("UnfreezeMap")]
@ -329,19 +331,17 @@ namespace Server
NullP3D, NullP3D, UnfreezeWarning_Callback);
}
private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end)
{
SendWarning(from, "You are about to unfreeze a section of items.", BaseUnfreezeWarning, map, start, end,
UnfreezeWarning_Callback);
}
private static void UnfreezeWarning_Callback(Mobile from, bool okay, object state)
private static void UnfreezeWarning_Callback(Mobile from, bool okay, StateInfo si)
{
if (!okay)
return;
StateInfo si = (StateInfo)state;
Unfreeze(from, si.m_Map, si.m_Start, si.m_End);
}
@ -378,9 +378,8 @@ namespace Server
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);
matrix.BlockHeight, out int oldTileCount);
if (oldTileCount < 0)
continue;
@ -493,11 +492,11 @@ namespace Server
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));
0xFFC000, 320, 240));
else
from.SendGump(new NoticeGump(1060637, 30720,
$"Unfreeze operation completed successfully.<br><br>{totalUnfrozen} item{(totalUnfrozen != 1 ? "s were" : " was")} unfrozen.<br><br>You must restart your client and update it's data files to see the changes.",
0xFFC000, 320, 240, null, null));
0xFFC000, 320, 240));
}
private static FileStream OpenWrite(FileStream orig)
@ -580,7 +579,7 @@ namespace Server
}
}
private class StateInfo
public class StateInfo
{
public Map m_Map;
public Point3D m_Start, m_End;
@ -593,4 +592,4 @@ namespace Server
}
}
}
}
}

View file

@ -54,12 +54,7 @@ namespace Server.Commands
public static void BeginWipe(Mobile from, WipeType type)
{
BoundingBoxPicker.Begin(from, WipeBox_Callback, type);
}
private static void WipeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
DoWipe(from, map, start, end, (WipeType)state);
BoundingBoxPicker.Begin(from, (map, start, end) => DoWipe(from, map, start, end, type));
}
public static void DoWipe(Mobile from, Map map, Point3D start, Point3D end, WipeType type)
@ -80,7 +75,7 @@ namespace Server.Commands
if (!items && !multis || !mobiles)
return;
eable = map.GetObjectsInBounds(rect, true, true);
eable = map.GetObjectsInBounds(rect);
foreach (IEntity obj in eable)
if (items && obj is Item && !(obj is BaseMulti || obj is HouseSign))