Fixes code according to modern code style. Fixes a few expression bugs.

This commit is contained in:
Kamron Batman 2018-09-15 09:58:51 -07:00
parent 89eea25e5f
commit 970fd563b2
3324 changed files with 441118 additions and 433755 deletions

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,3 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
@ -8,198 +7,204 @@ using Server.Targeting;
namespace Server.Commands.Generic
{
public class DesignInsertCommand : BaseCommand
{
public static void Initialize()
{
TargetCommands.Register( new DesignInsertCommand() );
}
public class DesignInsertCommand : BaseCommand
{
public enum DesignInsertResult
{
Valid,
InvalidItem,
NotInHouse,
OutsideHouseBounds
}
public DesignInsertCommand()
{
AccessLevel = AccessLevel.GameMaster;
Supports = CommandSupport.Single | CommandSupport.Area;
Commands = new[] { "DesignInsert" };
ObjectTypes = ObjectTypes.Items;
Usage = "DesignInsert [allItems=false]";
Description = "Inserts multiple targeted items into a customizable house's design.";
}
public DesignInsertCommand()
{
AccessLevel = AccessLevel.GameMaster;
Supports = CommandSupport.Single | CommandSupport.Area;
Commands = new[] { "DesignInsert" };
ObjectTypes = ObjectTypes.Items;
Usage = "DesignInsert [allItems=false]";
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 );
}
public static void Initialize()
{
TargetCommands.Register(new DesignInsertCommand());
}
private class DesignInsertTarget : Target
{
private List<HouseFoundation> m_Foundations;
private bool m_StaticsOnly;
public static DesignInsertResult ProcessInsert(Item item, bool staticsOnly, out HouseFoundation house)
{
house = null;
public DesignInsertTarget( List<HouseFoundation> foundations, bool staticsOnly )
: base( -1, false, TargetFlags.None )
{
m_Foundations = foundations;
m_StaticsOnly = staticsOnly;
}
if (item == null || item is BaseMulti || item is HouseSign || staticsOnly && !(item is Static))
return DesignInsertResult.InvalidItem;
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
{
if ( m_Foundations.Count != 0 )
{
from.SendMessage( "Your changes have been committed. Updating..." );
house = BaseHouse.FindHouseAt(item) as HouseFoundation;
foreach ( HouseFoundation house in m_Foundations )
house.Delta( ItemDelta.Update );
}
}
if (house == null)
return DesignInsertResult.NotInHouse;
protected override void OnTarget( Mobile from, object obj )
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert( obj as Item, m_StaticsOnly, out house );
int x = item.X - house.X;
int y = item.Y - house.Y;
int z = item.Z - house.Z;
switch ( result )
{
case DesignInsertResult.Valid:
{
if ( 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 (!TryInsertIntoState(house.CurrentState, item.ItemID, x, y, z))
return DesignInsertResult.OutsideHouseBounds;
if ( !m_Foundations.Contains( house ) )
m_Foundations.Add( house );
TryInsertIntoState(house.DesignState, item.ItemID, x, y, z);
item.Delete();
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;
}
}
return DesignInsertResult.Valid;
}
from.Target = new DesignInsertTarget( m_Foundations, m_StaticsOnly );
}
}
#endregion
private static bool TryInsertIntoState(DesignState state, int itemID, int x, int y, int z)
{
MultiComponentList mcl = state.Components;
#region Area targeting mode
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
e.Mobile.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 ) ) } ) );
AddResponse( "Awaiting confirmation..." );
}
if (x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y)
return false;
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];
mcl.Add(itemID, x, y, z);
state.OnRevised();
bool flushToLog = false;
return true;
}
if ( okay )
{
List<HouseFoundation> foundations = new List<HouseFoundation>();
flushToLog = ( list.Count > 20 );
#region Single targeting mode
for ( int i = 0; i < list.Count; ++i )
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert( list[i] as Item, staticsOnly, out house );
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);
}
switch ( result )
{
case DesignInsertResult.Valid:
{
AddResponse( "The item has been inserted into the house design." );
private class DesignInsertTarget : Target
{
private List<HouseFoundation> m_Foundations;
private bool m_StaticsOnly;
if ( !foundations.Contains( house ) )
foundations.Add( house );
public DesignInsertTarget(List<HouseFoundation> foundations, bool staticsOnly)
: base(-1, false, TargetFlags.None)
{
m_Foundations = foundations;
m_StaticsOnly = staticsOnly;
}
break;
}
case DesignInsertResult.InvalidItem:
{
LogFailure( "That cannot be inserted." );
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
LogFailure( "That item is not inside a customizable house." );
break;
}
}
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (m_Foundations.Count != 0)
{
from.SendMessage("Your changes have been committed. Updating...");
foreach ( HouseFoundation house in foundations )
house.Delta( ItemDelta.Update );
}
else
{
AddResponse( "Command aborted." );
}
foreach (HouseFoundation house in m_Foundations)
house.Delta(ItemDelta.Update);
}
}
Flush( from, flushToLog );
}
#endregion
protected override void OnTarget(Mobile from, object obj)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out house);
public enum DesignInsertResult
{
Valid,
InvalidItem,
NotInHouse,
OutsideHouseBounds
}
switch (result)
{
case DesignInsertResult.Valid:
{
if (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.");
public static DesignInsertResult ProcessInsert( Item item, bool staticsOnly, out HouseFoundation house )
{
house = null;
if (!m_Foundations.Contains(house))
m_Foundations.Add(house);
if ( item == null || item is BaseMulti || item is HouseSign || ( staticsOnly && !( item is Static ) ) )
return DesignInsertResult.InvalidItem;
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;
}
}
house = BaseHouse.FindHouseAt( item ) as HouseFoundation;
from.Target = new DesignInsertTarget(m_Foundations, m_StaticsOnly);
}
}
if ( house == null )
return DesignInsertResult.NotInHouse;
#endregion
int x = item.X - house.X;
int y = item.Y - house.Y;
int z = item.Z - house.Z;
#region Area targeting mode
if ( !TryInsertIntoState( house.CurrentState, item.ItemID, x, y, z ) )
return DesignInsertResult.OutsideHouseBounds;
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
e.Mobile.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) }));
AddResponse("Awaiting confirmation...");
}
TryInsertIntoState( house.DesignState, item.ItemID, x, y, z );
item.Delete();
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];
return DesignInsertResult.Valid;
}
bool flushToLog = false;
private static bool TryInsertIntoState( DesignState state, int itemID, int x, int y, int z )
{
MultiComponentList mcl = state.Components;
if (okay)
{
List<HouseFoundation> foundations = new List<HouseFoundation>();
flushToLog = list.Count > 20;
if ( x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y )
return false;
for (int i = 0; i < list.Count; ++i)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
mcl.Add( itemID, x, y, z );
state.OnRevised();
switch (result)
{
case DesignInsertResult.Valid:
{
AddResponse("The item has been inserted into the house design.");
return true;
}
}
}
if (!foundations.Contains(house))
foundations.Add(house);
break;
}
case DesignInsertResult.InvalidItem:
{
LogFailure("That cannot be inserted.");
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
LogFailure("That item is not inside a customizable house.");
break;
}
}
}
foreach (HouseFoundation house in foundations)
house.Delta(ItemDelta.Update);
}
else
{
AddResponse("Command aborted.");
}
Flush(from, flushToLog);
}
#endregion
}
}

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

@ -4,81 +4,82 @@ 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(); } );
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo =
new ExtensionInfo(30, "Distinct", -1, delegate { return new DistinctExtension(); });
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
private List<Property> m_Properties;
private List<Property> m_Properties;
public DistinctExtension()
{
m_Properties = new List<Property>();
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
public DistinctExtension()
{
m_Properties = new List<Property>();
}
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." );
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 m_Properties )
{
prop.BindTo( baseType, PropertyAccess.Read );
prop.CheckAccess( from );
}
foreach (Property prop in m_Properties)
{
prop.BindTo(baseType, PropertyAccess.Read);
prop.CheckAccess(from);
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = DistinctCompiler.Compile( assembly, baseType, m_Properties.ToArray() );
}
m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray());
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid distinction syntax." );
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;
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
while (offset < end)
{
string binding = arguments[offset++];
m_Properties.Add( new Property( binding ) );
}
}
m_Properties.Add(new Property(binding));
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
public override void Filter(ArrayList list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
ArrayList copy = new ArrayList( list );
ArrayList copy = new ArrayList(list);
copy.Sort( m_Comparer );
copy.Sort(m_Comparer);
list.Clear();
list.Clear();
object last = null;
object last = null;
for ( int i = 0; i < copy.Count; ++i )
{
object obj = copy[i];
for (int i = 0; i < copy.Count; ++i)
{
object obj = copy[i];
if ( last == null || m_Comparer.Compare( obj, last ) != 0 )
{
list.Add( obj );
last = obj;
}
}
}
}
}
if (last == null || m_Comparer.Compare(obj, last) != 0)
{
list.Add(obj);
last = obj;
}
}
}
}
}

View file

@ -3,35 +3,31 @@ 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(); } );
public sealed class LimitExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(80, "Limit", 1, delegate { return new LimitExtension(); });
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info => ExtInfo;
public override ExtensionInfo Info => ExtInfo;
public int Limit{ get; private set; }
public int Limit { get; private set; }
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public LimitExtension()
{
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
Limit = Utility.ToInt32(arguments[offset]);
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
Limit = Utility.ToInt32( arguments[offset] );
if (Limit < 0)
throw new Exception("Limit cannot be less than zero.");
}
if ( Limit < 0 )
throw new Exception( "Limit cannot be less than zero." );
}
public override void Filter( ArrayList list )
{
if ( list.Count > Limit )
list.RemoveRange( Limit, list.Count - Limit );
}
}
}
public override void Filter(ArrayList list)
{
if (list.Count > Limit)
list.RemoveRange(Limit, list.Count - Limit);
}
}
}

View file

@ -4,101 +4,101 @@ 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(); } );
public sealed class SortExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(40, "Order", -1, delegate { return new SortExtension(); });
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
private List<OrderInfo> m_Orders;
private List<OrderInfo> m_Orders;
public SortExtension()
{
m_Orders = new List<OrderInfo>();
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
public SortExtension()
{
m_Orders = new List<OrderInfo>();
}
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." );
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 m_Orders )
{
order.Property.BindTo( baseType, PropertyAccess.Read );
order.Property.CheckAccess( from );
}
foreach (OrderInfo order in m_Orders)
{
order.Property.BindTo(baseType, PropertyAccess.Read);
order.Property.CheckAccess(from);
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = SortCompiler.Compile( assembly, baseType, m_Orders.ToArray() );
}
m_Comparer = SortCompiler.Compile(assembly, baseType, m_Orders.ToArray());
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
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 (Insensitive.Equals(arguments[offset], "by"))
{
++offset;
--size;
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
}
if (size < 1)
throw new Exception("Invalid ordering syntax.");
}
int end = offset + size;
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
while (offset < end)
{
string binding = arguments[offset++];
bool isAscending = true;
bool isAscending = true;
if ( offset < end )
{
string next = arguments[offset];
if (offset < end)
{
string next = arguments[offset];
switch ( next.ToLower() )
{
case "+":
case "up":
case "asc":
case "ascending":
isAscending = true;
++offset;
break;
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;
}
}
case "-":
case "down":
case "desc":
case "descending":
isAscending = false;
++offset;
break;
}
}
Property property = new Property( binding );
Property property = new Property(binding);
m_Orders.Add( new OrderInfo( property, isAscending ) );
}
}
m_Orders.Add(new OrderInfo(property, isAscending));
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
public override void Filter(ArrayList list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
list.Sort( m_Comparer );
}
}
}
list.Sort(m_Comparer);
}
}
}

View file

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

View file

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

View file

@ -5,299 +5,294 @@ 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,
[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),
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
}
Simple = Single | Multi,
Complex = Global | Online | Area | Region | Contained | IPAddress
}
public abstract class BaseCommandImplementor
{
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() );
public abstract class BaseCommandImplementor
{
private static List<BaseCommandImplementor> m_Implementors;
Register( new RangeCommandImplementor() );
Register( new ScreenCommandImplementor() );
Register( new FacetCommandImplementor() );
}
public BaseCommandImplementor()
{
Commands = new Dictionary<string, BaseCommand>(StringComparer.OrdinalIgnoreCase);
}
public bool SupportsConditionals { get; set; }
public bool SupportsConditionals{ get; set; }
public string[] Accessors { get; set; }
public string[] Accessors{ get; set; }
public string Usage { get; set; }
public string Usage{ get; set; }
public string Description { get; set; }
public string Description{ get; set; }
public AccessLevel AccessLevel { get; set; }
public AccessLevel AccessLevel{ get; set; }
public CommandSupport SupportRequirement { get; set; }
public CommandSupport SupportRequirement{ get; set; }
public Dictionary<string, BaseCommand> Commands { get; }
public Dictionary<string, BaseCommand> Commands{ get; }
public BaseCommandImplementor()
{
Commands = new Dictionary<string, BaseCommand>( StringComparer.OrdinalIgnoreCase );
}
public static List<BaseCommandImplementor> Implementors
{
get
{
if (m_Implementors == null)
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
public virtual void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
obj = null;
}
return m_Implementors;
}
}
public virtual void Register( BaseCommand command )
{
for ( int i = 0; i < command.Commands.Length; ++i )
Commands[command.Commands[i]] = command;
}
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());
public bool CheckObjectTypes( Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles )
{
items = mobiles = false;
Register(new RangeCommandImplementor());
Register(new ScreenCommandImplementor());
Register(new FacetCommandImplementor());
}
ObjectConditional cond = ObjectConditional.Empty;
public virtual void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
obj = null;
}
foreach ( BaseExtension check in ext )
{
if ( check is WhereExtension extension )
{
cond = extension.Conditional;
public virtual void Register(BaseCommand command)
{
for (int i = 0; i < command.Commands.Length; ++i)
Commands[command.Commands[i]] = command;
}
break;
}
}
public bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles)
{
items = mobiles = false;
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
ObjectConditional cond = ObjectConditional.Empty;
switch ( command.ObjectTypes )
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if ( condIsItem )
items = true;
foreach (BaseExtension check in ext)
if (check is WhereExtension extension)
{
cond = extension.Conditional;
if ( condIsMobile )
mobiles = true;
break;
}
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;
}
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
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;
}
switch (command.ObjectTypes)
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if (condIsItem)
items = true;
break;
}
}
if (condIsMobile)
mobiles = true;
return 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;
}
public void RunCommand( Mobile from, BaseCommand command, string[] args )
{
try
{
object obj = null;
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;
}
Compile( from, command, ref args, ref obj );
break;
}
}
RunCommand( from, obj, command, args );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
return true;
}
public string GenerateArgString( string[] args )
{
if ( args.Length == 0 )
return "";
public void RunCommand(Mobile from, BaseCommand command, string[] args)
{
try
{
object obj = null;
// NOTE: this does not preserve the case where quotation marks are used on a single word
Compile(from, command, ref args, ref obj);
StringBuilder sb = new StringBuilder();
RunCommand(from, obj, command, args);
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
for ( int i = 0; i < args.Length; ++i )
{
if ( i > 0 )
sb.Append( ' ' );
public string GenerateArgString(string[] args)
{
if (args.Length == 0)
return "";
if ( args[i].IndexOf( ' ' ) >= 0 )
{
sb.Append( '"' );
sb.Append( args[i] );
sb.Append( '"' );
}
else
{
sb.Append( args[i] );
}
}
// NOTE: this does not preserve the case where quotation marks are used on a single word
return sb.ToString();
}
StringBuilder sb = new StringBuilder();
public void RunCommand( Mobile from, object obj, BaseCommand command, string[] args )
{
// try
// {
CommandEventArgs e = new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args );
for (int i = 0; i < args.Length; ++i)
{
if (i > 0)
sb.Append(' ');
if ( !command.ValidateArgs( this, e ) )
return;
if (args[i].IndexOf(' ') >= 0)
{
sb.Append('"');
sb.Append(args[i]);
sb.Append('"');
}
else
{
sb.Append(args[i]);
}
}
bool flushToLog = false;
return sb.ToString();
}
if ( obj is ArrayList list )
{
if ( list.Count > 20 )
CommandLogging.Enabled = false;
else if ( list.Count == 0 )
command.LogFailure( "Nothing was found to use this command on." );
public void RunCommand(Mobile from, object obj, BaseCommand command, string[] args)
{
// try
// {
CommandEventArgs e = new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args);
command.ExecuteList( e, list );
if (!command.ValidateArgs(this, e))
return;
if ( list.Count > 20 )
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if ( obj != null )
{
if ( command.ListOptimized )
{
command.ExecuteList( e, new ArrayList{ obj } );
}
else
{
command.Execute( e, obj );
}
}
bool flushToLog = false;
command.Flush( from, flushToLog );
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
if (obj is ArrayList list)
{
if (list.Count > 20)
CommandLogging.Enabled = false;
else if (list.Count == 0)
command.LogFailure("Nothing was found to use this command on.");
public virtual void Process( Mobile from, BaseCommand command, string[] args )
{
RunCommand( from, command, args );
}
command.ExecuteList(e, list);
public virtual void Execute( CommandEventArgs e )
{
if ( e.Length >= 1 )
{
Commands.TryGetValue( e.GetString( 0 ), out BaseCommand command );
if (list.Count > 20)
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if (obj != null)
{
if (command.ListOptimized)
command.ExecuteList(e, new ArrayList { obj });
else
command.Execute(e, obj);
}
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];
command.Flush(from, flushToLog);
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 1];
public virtual void Process(Mobile from, BaseCommand command, string[] args)
{
RunCommand(from, command, args);
}
Process( e.Mobile, command, args );
}
}
else
{
e.Mobile.SendMessage( "You must supply a command name." );
}
}
public virtual void Execute(CommandEventArgs e)
{
if (e.Length >= 1)
{
Commands.TryGetValue(e.GetString(0), out BaseCommand command);
public void Register()
{
if ( Accessors == null )
return;
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 < Accessors.Length; ++i )
CommandSystem.Register( Accessors[i], AccessLevel, Execute );
}
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 1];
public static void Register( BaseCommandImplementor impl )
{
m_Implementors.Add( impl );
impl.Register();
}
Process(e.Mobile, command, args);
}
}
else
{
e.Mobile.SendMessage("You must supply a command name.");
}
}
private static List<BaseCommandImplementor> m_Implementors;
public void Register()
{
if (Accessors == null)
return;
public static List<BaseCommandImplementor> Implementors
{
get
{
if ( m_Implementors == null )
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
for (int i = 0; i < Accessors.Length; ++i)
CommandSystem.Register(Accessors[i], AccessLevel, Execute);
}
return m_Implementors;
}
}
}
}
public static void Register(BaseCommandImplementor impl)
{
m_Implementors.Add(impl);
impl.Register();
}
}
}

View file

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

View file

@ -1,30 +1,32 @@
namespace Server.Commands.Generic
{
public class FacetCommandImplementor : BaseCommandImplementor
{
public FacetCommandImplementor()
{
Accessors = new[]{ "Facet" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Facet <command> [condition]";
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 class FacetCommandImplementor : BaseCommandImplementor
{
public FacetCommandImplementor()
{
Accessors = new[] { "Facet" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Facet <command> [condition]";
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;
public override void Process(Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if ( impl == null )
return;
if (impl == null)
return;
Map map = from.Map;
Map map = from.Map;
if ( map == null || map == Map.Internal )
return;
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),
new object[] { command, args });
}
}
}

View file

@ -3,57 +3,50 @@ using System.Collections;
namespace Server.Commands.Generic
{
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
Accessors = new[]{ "Global" };
SupportRequirement = CommandSupport.Global;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "Global <command> [condition]";
Description = "Invokes the command on all appropriate objects in the world. Optional condition arguments can further restrict the set of objects.";
}
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
Accessors = new[] { "Global" };
SupportRequirement = CommandSupport.Global;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "Global <command> [condition]";
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 );
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;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
ArrayList list = new ArrayList();
ArrayList list = new ArrayList();
if ( items )
{
foreach ( Item item in World.Items.Values )
{
if ( ext.IsValid( item ) )
list.Add( item );
}
}
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 );
}
}
if (mobiles)
foreach (Mobile mob in World.Mobiles.Values)
if (ext.IsValid(mob))
list.Add(mob);
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -1,63 +1,65 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Network;
namespace Server.Commands.Generic
{
public class IPAddressCommandImplementor : BaseCommandImplementor
{
public IPAddressCommandImplementor()
{
Accessors = new[]{ "IPAddress" };
SupportRequirement = CommandSupport.IPAddress;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "IPAddress <command> [condition]";
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 class IPAddressCommandImplementor : BaseCommandImplementor
{
public IPAddressCommandImplementor()
{
Accessors = new[] { "IPAddress" };
SupportRequirement = CommandSupport.IPAddress;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "IPAddress <command> [condition]";
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 );
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;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if ( !mobiles ) // sanity check
{
command.LogFailure( "This command does not support items." );
return;
}
if (!mobiles) // sanity check
{
command.LogFailure("This command does not support items.");
return;
}
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
System.Collections.Generic.List<NetState> states = NetState.Instances;
List<NetState> states = NetState.Instances;
for ( int i = 0; i < states.Count; ++i )
{
NetState ns = (NetState)states[i];
Mobile mob = ns.Mobile;
for (int i = 0; i < states.Count; ++i)
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
if ( mob != null && !addresses.Contains( ns.Address ) && ext.IsValid( mob ) )
{
list.Add( mob );
addresses.Add( ns.Address );
}
}
if (mob != null && !addresses.Contains(ns.Address) && ext.IsValid(mob))
{
list.Add(mob);
addresses.Add(ns.Address);
}
}
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -2,73 +2,76 @@ using Server.Targeting;
namespace Server.Commands.Generic
{
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
Accessors = new[]{ "Multi", "m" };
SupportRequirement = CommandSupport.Multi;
AccessLevel = AccessLevel.Counselor;
Usage = "Multi <command>";
Description = "Invokes the command on multiple targeted objects.";
}
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
Accessors = new[] { "Multi", "m" };
SupportRequirement = CommandSupport.Multi;
AccessLevel = AccessLevel.Counselor;
Usage = "Multi <command>";
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], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
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 });
}
public void OnTarget( Mobile from, object targeted, object state )
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
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;
}
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;
}
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.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;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
break;
}
}
RunCommand( from, targeted, command, args );
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, new TargetStateCallback(OnTarget),
new object[] { command, args });
}
}
}

View file

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

View file

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

View file

@ -1,77 +1,79 @@
namespace Server.Commands.Generic
{
public class RangeCommandImplementor : BaseCommandImplementor
{
public static RangeCommandImplementor Instance { get; private set; }
public class RangeCommandImplementor : BaseCommandImplementor
{
public RangeCommandImplementor()
{
Accessors = new[] { "Range" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Range <range> <command> [condition]";
Description =
"Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
public RangeCommandImplementor()
{
Accessors = new[]{ "Range" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Range <range> <command> [condition]";
Description = "Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
Instance = this;
}
Instance = this;
}
public static RangeCommandImplementor Instance{ get; private set; }
public override void Execute( CommandEventArgs e )
{
if ( e.Length >= 2 )
{
int range = e.GetInt32( 0 );
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
{
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
if (range < 0)
{
e.Mobile.SendMessage("The range must not be negative.");
}
else
{
Commands.TryGetValue(e.GetString(1), out BaseCommand 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];
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];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
Process( range, e.Mobile, command, args );
}
}
}
else
{
e.Mobile.SendMessage( "You must supply a range and a command name." );
}
}
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;
public void Process(int range, Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if ( impl == null )
return;
if (impl == null)
return;
Map map = from.Map;
Map map = from.Map;
if ( map == null || map == Map.Internal )
return;
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 );
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, new object[] { command, args });
}
}
}

View file

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

View file

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

View file

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

View file

@ -1,95 +1,96 @@
namespace Server.Commands.Generic
{
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
Accessors = new[]{ "Serial" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Serial <serial> <command>";
Description = "Invokes the command on a single object by serial.";
}
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
Accessors = new[] { "Serial" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Serial <serial> <command>";
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 );
public override void Execute(CommandEventArgs e)
{
if (e.Length >= 2)
{
Serial serial = e.GetInt32(0);
object obj = null;
object obj = null;
if ( serial.IsItem )
obj = World.FindItem( serial );
else if ( serial.IsMobile )
obj = World.FindMobile( serial );
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
{
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
if (obj == null)
{
e.Mobile.SendMessage("That is not a valid serial.");
}
else
{
Commands.TryGetValue(e.GetString(1), out BaseCommand 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;
}
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.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;
}
case ObjectTypes.Mobiles:
{
if ( !(obj is Mobile) )
{
e.Mobile.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
}
break;
}
}
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 2];
RunCommand( e.Mobile, obj, command, args );
}
}
}
else
{
e.Mobile.SendMessage( "You must supply an object serial and a command name." );
}
}
}
}
RunCommand(e.Mobile, obj, command, args);
}
}
}
else
{
e.Mobile.SendMessage("You must supply an object serial and a command name.");
}
}
}
}

View file

@ -2,90 +2,92 @@ using Server.Targeting;
namespace Server.Commands.Generic
{
public class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new[]{ "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 class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new[] { "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 );
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, Redirect );
}
for (int i = 0; i < command.Commands.Length; ++i)
CommandSystem.Register(command.Commands[i], command.AccessLevel, Redirect);
}
public void Redirect( CommandEventArgs e )
{
Commands.TryGetValue( e.Command, out BaseCommand command );
public void Redirect(CommandEventArgs e)
{
Commands.TryGetValue(e.Command, out BaseCommand 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 ) )
Process( e.Mobile, command, e.Arguments );
}
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))
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], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
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 });
}
public void OnTarget( Mobile from, object targeted, object state )
{
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
return;
}
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];
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;
}
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.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;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
break;
}
}
RunCommand( from, targeted, command, args );
}
}
}
RunCommand(from, targeted, command, args);
}
}
}