fix(cleanup): Consolidate the duplicate code in Properties, PropsGump, and PropsConfig (#540)
This commit is contained in:
parent
98ce65083a
commit
dd2933a9ef
21 changed files with 335 additions and 761 deletions
|
|
@ -1,13 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Server.Types;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class ObjectConditional
|
||||
{
|
||||
private static readonly Type typeofItem = typeof(Item);
|
||||
private static readonly Type typeofMobile = typeof(Mobile);
|
||||
|
||||
public static readonly ObjectConditional Empty = new(null, null);
|
||||
|
||||
private readonly ICondition[][] m_Conditions;
|
||||
|
|
@ -22,9 +21,9 @@ namespace Server.Commands.Generic
|
|||
|
||||
public Type Type { get; }
|
||||
|
||||
public bool IsItem => Type == null || Type == typeofItem || Type.IsSubclassOf(typeofItem);
|
||||
public bool IsItem => Type == null || Type.IsAssignableTo(OfItem);
|
||||
|
||||
public bool IsMobile => Type == null || Type == typeofMobile || Type.IsSubclassOf(typeofMobile);
|
||||
public bool IsMobile => Type == null || Type.IsAssignableTo(OfMobile);
|
||||
|
||||
public bool HasCompiled => m_Conditionals != null;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,39 +6,15 @@ using System.Text;
|
|||
using Server.Items;
|
||||
using CPA = Server.CommandPropertyAttribute;
|
||||
|
||||
using static Server.Attributes;
|
||||
using static Server.Types;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public static class Add
|
||||
{
|
||||
private static readonly Type m_EntityType = typeof(IEntity);
|
||||
|
||||
private static readonly Type m_ConstructibleType = typeof(ConstructibleAttribute);
|
||||
|
||||
private static readonly Type m_EnumType = typeof(Enum);
|
||||
|
||||
private static readonly Type m_TypeType = typeof(Type);
|
||||
|
||||
private static readonly Type m_ParsableType = typeof(ParsableAttribute);
|
||||
|
||||
private static readonly Type[] m_ParseTypes = { typeof(string) };
|
||||
private static readonly object[] m_ParseArgs = new object[1];
|
||||
|
||||
private static readonly Type[] m_SignedNumerics =
|
||||
{
|
||||
typeof(long),
|
||||
typeof(int),
|
||||
typeof(short),
|
||||
typeof(sbyte)
|
||||
};
|
||||
|
||||
private static readonly Type[] m_UnsignedNumerics =
|
||||
{
|
||||
typeof(ulong),
|
||||
typeof(uint),
|
||||
typeof(ushort),
|
||||
typeof(byte)
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Tile", AccessLevel.GameMaster, Tile_OnCommand);
|
||||
|
|
@ -193,7 +169,7 @@ namespace Server.Commands
|
|||
}
|
||||
else
|
||||
{
|
||||
var attr = Properties.GetCPA(thisProp);
|
||||
var attr = GetCPA(thisProp);
|
||||
|
||||
if (attr == null)
|
||||
{
|
||||
|
|
@ -759,56 +735,21 @@ namespace Server.Commands
|
|||
InternalAvg_OnCommand(e, true);
|
||||
}
|
||||
|
||||
public static bool IsEntity(Type t) => m_EntityType.IsAssignableFrom(t);
|
||||
public static bool IsEnum(Type type) => type.IsSubclassOf(OfEnum);
|
||||
|
||||
public static bool IsConstructible(ConstructorInfo ctor, AccessLevel accessLevel)
|
||||
{
|
||||
var attrs = ctor.GetCustomAttributes(m_ConstructibleType, false);
|
||||
public static bool IsType(Type type) => type == OfType || type.IsSubclassOf(OfType);
|
||||
|
||||
return attrs.Length != 0 && accessLevel >= ((ConstructibleAttribute)attrs[0]).AccessLevel;
|
||||
}
|
||||
|
||||
public static bool IsEnum(Type type) => type.IsSubclassOf(m_EnumType);
|
||||
|
||||
public static bool IsType(Type type) => type == m_TypeType || type.IsSubclassOf(m_TypeType);
|
||||
|
||||
public static bool IsParsable(Type type) => type.IsDefined(m_ParsableType, false);
|
||||
public static bool IsParsable(Type type) => type.IsDefined(OfParsable, false);
|
||||
|
||||
public static object ParseParsable(Type type, string value)
|
||||
{
|
||||
var method = type.GetMethod("Parse", m_ParseTypes);
|
||||
var method = type.GetMethod("Parse", ParseTypes);
|
||||
|
||||
m_ParseArgs[0] = value;
|
||||
|
||||
return method?.Invoke(null, m_ParseArgs);
|
||||
}
|
||||
|
||||
public static bool IsSignedNumeric(Type type)
|
||||
{
|
||||
for (var i = 0; i < m_SignedNumerics.Length; ++i)
|
||||
{
|
||||
if (type == m_SignedNumerics[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsUnsignedNumeric(Type type)
|
||||
{
|
||||
for (var i = 0; i < m_UnsignedNumerics.Length; ++i)
|
||||
{
|
||||
if (type == m_UnsignedNumerics[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private enum TileZType
|
||||
{
|
||||
Start,
|
||||
|
|
|
|||
|
|
@ -2,55 +2,19 @@ using System;
|
|||
using Server.Commands;
|
||||
using Server.Network;
|
||||
|
||||
using static Server.Gumps.PropsConfig;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class CategorizedAddGump : Gump
|
||||
{
|
||||
public static bool OldStyle = PropsConfig.OldStyle;
|
||||
private static readonly int EntryHeight = PropsConfig.EntryHeight + 4;
|
||||
|
||||
public static readonly int EntryHeight = 24; // PropsConfig.EntryHeight;
|
||||
private static readonly int SetOffsetY = PropsConfig.SetOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
public static readonly int OffsetSize = PropsConfig.OffsetSize;
|
||||
public static readonly int BorderSize = PropsConfig.BorderSize;
|
||||
private static readonly int PrevOffsetY = PropsConfig.PrevOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
|
||||
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
|
||||
|
||||
public static readonly int TextHue = PropsConfig.TextHue;
|
||||
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
|
||||
|
||||
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
|
||||
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
|
||||
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
|
||||
public static readonly int BackGumpID = PropsConfig.BackGumpID;
|
||||
public static readonly int SetGumpID = PropsConfig.SetGumpID;
|
||||
|
||||
public static readonly int SetWidth = PropsConfig.SetWidth;
|
||||
|
||||
public static readonly int SetOffsetX = PropsConfig.SetOffsetX,
|
||||
SetOffsetY = PropsConfig.SetOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
|
||||
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
|
||||
|
||||
public static readonly int PrevWidth = PropsConfig.PrevWidth;
|
||||
|
||||
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX,
|
||||
PrevOffsetY = PropsConfig.PrevOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
|
||||
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
|
||||
|
||||
public static readonly int NextWidth = PropsConfig.NextWidth;
|
||||
|
||||
public static readonly int NextOffsetX = PropsConfig.NextOffsetX,
|
||||
NextOffsetY = PropsConfig.NextOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
|
||||
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
|
||||
|
||||
private static readonly bool PrevLabel = false;
|
||||
private static readonly bool NextLabel = false;
|
||||
private static readonly int NextOffsetY = PropsConfig.NextOffsetY + (EntryHeight - 20) / 2 / 2;
|
||||
|
||||
private static readonly int PrevLabelOffsetX = PrevWidth + 1;
|
||||
private static readonly int PrevLabelOffsetY = 0;
|
||||
|
|
@ -62,10 +26,9 @@ namespace Server.Gumps
|
|||
private static readonly int EntryCount = 15;
|
||||
|
||||
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
|
||||
private static readonly int TotalHeight = OffsetSize + (EntryHeight + OffsetSize) * (EntryCount + 1);
|
||||
|
||||
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
|
||||
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
|
||||
|
||||
private readonly CAGCategory m_Category;
|
||||
|
||||
private readonly Mobile m_Owner;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ using Server.Gumps;
|
|||
using Server.Targeting;
|
||||
using CPA = Server.CommandPropertyAttribute;
|
||||
|
||||
using static Server.Attributes;
|
||||
using static Server.Types;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
[Flags]
|
||||
|
|
@ -18,32 +21,8 @@ namespace Server.Commands
|
|||
|
||||
public static class Properties
|
||||
{
|
||||
private static readonly Type typeofCPA = typeof(CPA);
|
||||
|
||||
private static readonly Type typeofSerial = typeof(Serial);
|
||||
|
||||
private static readonly Type typeofType = typeof(Type);
|
||||
|
||||
private static readonly Type typeofChar = typeof(char);
|
||||
|
||||
private static readonly Type typeofString = typeof(string);
|
||||
|
||||
private static readonly Type typeofText = typeof(TextDefinition);
|
||||
|
||||
private static readonly Type typeofTimeSpan = typeof(TimeSpan);
|
||||
private static readonly Type typeofParsable = typeof(ParsableAttribute);
|
||||
|
||||
private static readonly Type[] m_ParseTypes = { typeof(string) };
|
||||
private static readonly object[] m_ParseParams = new object[1];
|
||||
|
||||
private static readonly Type[] m_NumericTypes =
|
||||
{
|
||||
typeof(byte), typeof(sbyte),
|
||||
typeof(short), typeof(ushort),
|
||||
typeof(int), typeof(uint),
|
||||
typeof(long), typeof(ulong)
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Props", AccessLevel.Counselor, Props_OnCommand);
|
||||
|
|
@ -78,18 +57,6 @@ namespace Server.Commands
|
|||
|
||||
private static bool CIEqual(string l, string r) => l.InsensitiveEquals(r);
|
||||
|
||||
public static CPA GetCPA(PropertyInfo p)
|
||||
{
|
||||
var attrs = p.GetCustomAttributes(typeofCPA, false);
|
||||
|
||||
if (attrs.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return attrs[0] as CPA;
|
||||
}
|
||||
|
||||
public static PropertyInfo[] GetPropertyInfoChain(
|
||||
Mobile from, Type type, string propertyString,
|
||||
PropertyAccess endAccess, ref string failReason
|
||||
|
|
@ -401,31 +368,15 @@ namespace Server.Commands
|
|||
return p == null ? failReason : InternalSetValue(from, logObject, o, p, name, value, true);
|
||||
}
|
||||
|
||||
private static bool IsSerial(Type t) => t == typeofSerial;
|
||||
|
||||
private static bool IsType(Type t) => t == typeofType;
|
||||
|
||||
private static bool IsChar(Type t) => t == typeofChar;
|
||||
|
||||
private static bool IsString(Type t) => t == typeofString;
|
||||
|
||||
private static bool IsText(Type t) => t == typeofText;
|
||||
|
||||
private static bool IsEnum(Type t) => t.IsEnum;
|
||||
|
||||
private static bool IsParsable(Type t) => t == typeofTimeSpan || t.IsDefined(typeofParsable, false);
|
||||
|
||||
private static object Parse(object o, Type t, string value)
|
||||
{
|
||||
var method = t.GetMethod("Parse", m_ParseTypes);
|
||||
var method = t.GetMethod("Parse", ParseTypes);
|
||||
|
||||
m_ParseParams[0] = value;
|
||||
|
||||
return method?.Invoke(o, m_ParseParams);
|
||||
}
|
||||
|
||||
private static bool IsNumeric(Type t) => Array.IndexOf(m_NumericTypes, t) >= 0;
|
||||
|
||||
public static string ConstructFromString(Type type, object obj, string value, ref object constructed)
|
||||
{
|
||||
object toSet;
|
||||
|
|
@ -433,7 +384,7 @@ namespace Server.Commands
|
|||
|
||||
if (isSerial) // mutate into int32
|
||||
{
|
||||
type = m_NumericTypes[4];
|
||||
type = OfInt;
|
||||
}
|
||||
|
||||
if (value == "(-null-)" && !type.IsValueType)
|
||||
|
|
@ -621,111 +572,6 @@ namespace Server.Commands
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public abstract class PropertyException : Exception
|
||||
{
|
||||
protected Property m_Property;
|
||||
|
||||
public PropertyException(Property property, string message)
|
||||
: base(message) =>
|
||||
m_Property = property;
|
||||
|
||||
public Property Property => m_Property;
|
||||
}
|
||||
|
||||
public abstract class BindingException : PropertyException
|
||||
{
|
||||
public BindingException(Property property, string message)
|
||||
: base(property, message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class NotYetBoundException : BindingException
|
||||
{
|
||||
public NotYetBoundException(Property property)
|
||||
: base(property, "Property has not yet been bound.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AlreadyBoundException : BindingException
|
||||
{
|
||||
public AlreadyBoundException(Property property)
|
||||
: base(property, "Property has already been bound.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UnknownPropertyException : BindingException
|
||||
{
|
||||
public UnknownPropertyException(Property property, string current)
|
||||
: base(property, $"Property '{current}' not found.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ReadOnlyException : BindingException
|
||||
{
|
||||
public ReadOnlyException(Property property)
|
||||
: base(property, "Property is read-only.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WriteOnlyException : BindingException
|
||||
{
|
||||
public WriteOnlyException(Property property)
|
||||
: base(property, "Property is write-only.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AccessException : PropertyException
|
||||
{
|
||||
public AccessException(Property property, string message)
|
||||
: base(property, message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class InternalAccessException : AccessException
|
||||
{
|
||||
public InternalAccessException(Property property)
|
||||
: base(property, "Property is internal.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ClearanceException : AccessException
|
||||
{
|
||||
public ClearanceException(Property property, AccessLevel playerAccess, AccessLevel neededAccess, string accessType)
|
||||
: base(
|
||||
property,
|
||||
$"You must be at least {Mobile.GetAccessLevelName(neededAccess)} to {accessType} this property."
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public AccessLevel PlayerAccess { get; set; }
|
||||
public AccessLevel NeededAccess { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ReadAccessException : ClearanceException
|
||||
{
|
||||
public ReadAccessException(Property property, AccessLevel playerAccess, AccessLevel neededAccess)
|
||||
: base(property, playerAccess, neededAccess, "read")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WriteAccessException : ClearanceException
|
||||
{
|
||||
public WriteAccessException(Property property, AccessLevel playerAccess, AccessLevel neededAccess)
|
||||
: base(property, playerAccess, neededAccess, "write")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Property
|
||||
{
|
||||
private PropertyInfo[] m_Chain;
|
||||
|
|
@ -788,7 +634,7 @@ namespace Server
|
|||
access |= PropertyAccess.Read;
|
||||
}
|
||||
|
||||
var security = Properties.GetCPA(prop);
|
||||
var security = GetCPA(prop);
|
||||
|
||||
if (security == null)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue