private ArrayList GetGroups(Type objectType, IEnumerable <PropertyInfo> props) { Hashtable groups = new Hashtable(); foreach (PropertyInfo prop in props) { if (!prop.CanRead) { continue; } CPA attr = GetCPA(prop); if (attr == null || m_Mobile.AccessLevel < attr.ReadLevel) { continue; } Type type = prop.DeclaringType; bool die = false; if (type == null) { continue; } while (!die) { Type baseType = type.BaseType; if (baseType == null || baseType == _TypeOfObject) { die = true; } else if (baseType.GetProperty(prop.Name, prop.PropertyType) != null) { type = baseType; } else { die = true; } } ArrayList list = groups[type] as ArrayList; if (list == null) { groups[type] = list = new ArrayList(); } list.Add(prop); } ArrayList sorted = new ArrayList(groups); sorted.Sort(new GroupComparer(objectType)); return(sorted); }
private ArrayList GetGroups(Type objectType, PropertyInfo[] props) { Hashtable groups = new Hashtable(); for (int i = 0; i < props.Length; ++i) { PropertyInfo prop = props[i]; if (prop.CanRead) { CPA attr = GetCPA(prop); if (attr != null && m_Mobile.AccessLevel >= attr.ReadLevel) { Type type = prop.DeclaringType; while (true) { if (!(type is null)) { Type baseType = type.BaseType; if (baseType == null || baseType == typeofObject) { break; } if (baseType.GetProperty(prop.Name, prop.PropertyType) != null) { type = baseType; } else { break; } } } ArrayList list = (ArrayList)groups[type]; if (list == null) { groups[type] = list = new ArrayList(); } list.Add(prop); } } } ArrayList sorted = new ArrayList(groups); sorted.Sort(new GroupComparer(objectType)); return(sorted); }
private List <KeyValuePair <Type, List <PropertyInfo> > > GetGroups(Type objectType, PropertyInfo[] props) { Dictionary <Type, List <PropertyInfo> > groups = new Dictionary <Type, List <PropertyInfo> >(); for (int i = 0; i < props.Length; ++i) { PropertyInfo prop = props[i]; if (prop.CanRead) { CPA attr = GetCPA(prop); if (attr != null && m_Mobile.AccessLevel >= attr.ReadLevel) { Type type = prop.DeclaringType; while (true) { Type baseType = type?.BaseType; if (baseType == typeofObject || baseType?.GetProperty(prop.Name, prop.PropertyType) == null) { break; } type = baseType; } if (type != null && !groups.ContainsKey(type)) { groups[type] = new List <PropertyInfo> { prop } } ; else { groups[type].Add(prop); } } } } List <KeyValuePair <Type, List <PropertyInfo> > > list = groups.ToList(); list.Sort(new GroupComparer(objectType)); return(list); }
public bool HasAccess(Type type) { if (type != null) { PropertyInfo[] allProps = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo prop in allProps) { CPA attr = Properties.GetCPA(prop); if (attr != null && ((prop.CanRead && m_From.AccessLevel < attr.ReadLevel) || (prop.CanWrite && m_From.AccessLevel < attr.WriteLevel))) { m_From.SendMessage("The item {0} contains the property {1}, which you do not have access to.", type.Name, prop.Name); return(false); } } return(true); } return(false); }
public bool CheckAccess(Mobile from) { if (!IsBound) { throw new NotYetBoundException(this); } for (int i = 0; i < m_Chain.Length; ++i) { PropertyInfo prop = m_Chain[i]; bool isFinal = (i == (m_Chain.Length - 1)); PropertyAccess access = Access; if (!isFinal) { access |= PropertyAccess.Read; } CPA security = Properties.GetCPA(prop); if (security == null) { throw new InternalAccessException(this); } if ((access & PropertyAccess.Read) != 0 && from.AccessLevel < security.ReadLevel) { throw new ReadAccessException(this, from.AccessLevel, security.ReadLevel); } if ((access & PropertyAccess.Write) != 0 && (from.AccessLevel < security.WriteLevel || security.ReadOnly)) { throw new WriteAccessException(this, from.AccessLevel, security.ReadLevel); } } return(true); }
public static PropertyInfo[] GetPropertyInfoChain(Mobile from, Type type, string propertyString, PropertyAccess endAccess, ref string failReason) { string[] split = propertyString.Split('.'); if (split.Length == 0) { return(null); } PropertyInfo[] info = new PropertyInfo[split.Length]; for (int i = 0; i < info.Length; ++i) { string propertyName = split[i]; if (CIEqual(propertyName, "current")) { continue; } PropertyInfo[] props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); bool isFinal = i == info.Length - 1; PropertyAccess access = endAccess; if (!isFinal) { access |= PropertyAccess.Read; } for (int j = 0; j < props.Length; ++j) { PropertyInfo p = props[j]; if (CIEqual(p.Name, propertyName)) { CPA attr = GetCPA(p); if (attr == null) { failReason = $"Property '{propertyName}' not found."; return(null); } if ((access & PropertyAccess.Read) != 0 && from.AccessLevel < attr.ReadLevel) { failReason = $"You must be at least {Mobile.GetAccessLevelName(attr.ReadLevel)} to get the property '{propertyName}'."; return(null); } if ((access & PropertyAccess.Write) != 0 && from.AccessLevel < attr.WriteLevel) { failReason = $"You must be at least {Mobile.GetAccessLevelName(attr.WriteLevel)} to set the property '{propertyName}'."; return(null); } if ((access & PropertyAccess.Read) != 0 && !p.CanRead) { failReason = $"Property '{propertyName}' is write only."; return(null); } if ((access & PropertyAccess.Write) != 0 && (!p.CanWrite || attr.ReadOnly) && isFinal) { failReason = $"Property '{propertyName}' is read only."; return(null); } info[i] = p; type = p.PropertyType; break; } } if (info[i] == null) { failReason = $"Property '{propertyName}' not found."; return(null); } } return(info); }
/// <summary> /// Primary dupe method. Will be called recursively. /// </summary> /// <param name="from">Caller of the dupe command</param> /// <param name="toDupe">Item to be duped</param> /// <param name="recursionDepth">Recursions left</param> /// <param name="itemList">List of items created so far</param> /// <param name="mobileList">List of mobiles created so far</param> /// <param name="serialMapping">Mapping of serials of duped items and their copied counterparts</param> /// <returns>Duplicated entity</returns> public static object Dupe(Mobile from, object toDupe, int recursionDepth, List <Item> itemList, List <Mobile> mobileList, Dictionary <int, int> serialMapping) { object toReturn = null; Type type = toDupe.GetType(); // Getting all properties PropertyInfo[] allProps = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); // Checking if the caller's AccessLevel is high enough to write those foreach (PropertyInfo thisProp in allProps) { CPA attr = Properties.GetCPA(thisProp); if (attr != null && (from.AccessLevel < attr.ReadLevel || from.AccessLevel < attr.WriteLevel)) { // Ignoring all properties declared by BaseCreature and Mobile if (thisProp.DeclaringType != typeof(BaseCreature) && thisProp.DeclaringType != typeof(Mobile)) { throw new AccessLevelTooLowException("Your AccessLevel is too low to dupe this: " + thisProp.Name); } } } MemoryStream stream = new MemoryStream(); DupeWriter writer = new DupeWriter(stream, recursionDepth); DupeReader reader = new DupeReader(stream, from, itemList, mobileList, serialMapping); try { if (toDupe is Item) { Item item = (Item)toDupe; item.Serialize(writer); } else { Mobile mobile = (Mobile)toDupe; mobile.Serialize(writer); } // YAY! If we arrived here we are allowed to duplicate the item and have collected all necessary data writer.Flush(); reader.Seek(0, SeekOrigin.Begin); // Reset position of the reader // Fetch constructor with serial as parameter ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(Serial) }); if (toDupe is Item) { Item item = (Item)ctor.Invoke(new object[] { Serial.NewItem }); World.AddItem(item); // We don't want duplicate serials so we add it to the world right away to block its serial. serialMapping.Add(((Item)toDupe).Serial, item.Serial); itemList.Insert(0, item); // Insert at the beginning to reverse the recursive order item.Deserialize(reader); // Deserialize calls Dupe again if it reaches a reference. toReturn = item; } else if (toDupe is Mobile) { // Konstruktor mit Serial aufrufen Mobile mobile = (Mobile)ctor.Invoke(new object[] { Serial.NewMobile }); World.AddMobile(mobile); // We don't want duplicate serials so we add it to the world right away to block its serial. serialMapping.Add(((Mobile)toDupe).Serial, mobile.Serial); mobileList.Insert(0, mobile); // Insert at the beginning to reverse the recursive order mobile.Deserialize(reader); // Deserialize calls Dupe again if it reaches a reference. toReturn = mobile; } if (!reader.End()) { // The stream is not empty? throw new DeserializeException("Cannot dupe " + toReturn.GetType().Name + ". Serialize/Deserialize is either broken or uses hacks."); } if (itemList.Count + mobileList.Count > DupeCommand.MAX_ENTITIES) { throw new EntitiesExceededException("Cannot dupe more than " + DupeCommand.MAX_ENTITIES + " Items/Mobiles!"); } } finally { writer.Close(); reader.Close(); stream.Close(); } return(toReturn); }
public static ISpawnable Build(Type type, string[] args) { bool isISpawnable = typeof(ISpawnable).IsAssignableFrom(type); if (!isISpawnable) { return(null); } Add.FixArgs(ref args); string[,] props = null; for (int i = 0; i < args.Length; ++i) { if (Insensitive.Equals(args[i], "set")) { int remains = args.Length - i - 1; if (remains >= 2) { props = new string[remains / 2, 2]; remains /= 2; for (int j = 0; j < remains; ++j) { props[j, 0] = args[i + (j * 2) + 1]; props[j, 1] = args[i + (j * 2) + 2]; } Add.FixSetString(ref args, i); } break; } } PropertyInfo[] realProps = null; if (props != null) { realProps = new PropertyInfo[props.GetLength(0)]; PropertyInfo[] allProps = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); for (int i = 0; i < realProps.Length; ++i) { PropertyInfo thisProp = null; string propName = props[i, 0]; for (int j = 0; thisProp == null && j < allProps.Length; ++j) { if (Insensitive.Equals(propName, allProps[j].Name)) { thisProp = allProps[j]; } } if (thisProp != null) { CPA attr = Properties.GetCPA(thisProp); if (attr != null && AccessLevel.Spawner >= attr.WriteLevel && thisProp.CanWrite && !attr.ReadOnly) { realProps[i] = thisProp; } } } } ConstructorInfo[] ctors = type.GetConstructors(); for (int i = 0; i < ctors.Length; ++i) { ConstructorInfo ctor = ctors[i]; if (!Add.IsConstructable(ctor, AccessLevel.Spawner)) { continue; } ParameterInfo[] paramList = ctor.GetParameters(); if (args.Length == paramList.Length) { object[] paramValues = Add.ParseValues(paramList, args); if (paramValues == null) { continue; } object built = ctor.Invoke(paramValues); if (built != null && realProps != null) { for (int j = 0; j < realProps.Length; ++j) { if (realProps[j] == null) { continue; } Properties.InternalSetValue(built, realProps[j], props[j, 1]); } } return((ISpawnable)built); } } return(null); }
private void Initialize(int page) { m_Page = page; int count = m_List.Count - (page * EntryCount); if (count < 0) { count = 0; } else if (count > EntryCount) { count = EntryCount; } int lastIndex = (page * EntryCount) + count - 1; if (lastIndex >= 0 && lastIndex < m_List.Count && m_List[lastIndex] == null) { --count; } int totalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (count + 1)); AddPage(0); AddBackground(0, 0, BackWidth, BorderSize + totalHeight + BorderSize, BackGumpID); AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), totalHeight, OffsetGumpID); int x = BorderSize + OffsetSize; int y = BorderSize + OffsetSize; int emptyWidth = TotalWidth - PrevWidth - NextWidth - (OffsetSize * 4) - (OldStyle ? SetWidth + OffsetSize : 0); if (OldStyle) { AddImageTiled(x, y, TotalWidth - (OffsetSize * 3) - SetWidth, EntryHeight, HeaderGumpID); } else { AddImageTiled(x, y, PrevWidth, EntryHeight, HeaderGumpID); } if (page > 0) { AddButton(x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 1, GumpButtonType.Reply, 0); if (PrevLabel) { AddLabel(x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous"); } } x += PrevWidth + OffsetSize; if (!OldStyle) { AddImageTiled(x, y, emptyWidth, EntryHeight, HeaderGumpID); } if (TypeLabel && m_Type != null) { AddHtml( x, y, emptyWidth, EntryHeight, string.Format("<BASEFONT COLOR=#FAFAFA><CENTER>{0}</CENTER></BASEFONT>", m_Type.Name), false, false); } x += emptyWidth + OffsetSize; if (!OldStyle) { AddImageTiled(x, y, NextWidth, EntryHeight, HeaderGumpID); } if ((page + 1) * EntryCount < m_List.Count) { AddButton(x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 2, GumpButtonType.Reply, 1); if (NextLabel) { AddLabel(x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next"); } } for (int i = 0, index = page * EntryCount; i < count && index < m_List.Count; ++i, ++index) { x = BorderSize + OffsetSize; y += EntryHeight + OffsetSize; object o = m_List[index]; if (o is Type) { Type type = (Type)o; AddImageTiled(x, y, TypeWidth, EntryHeight, EntryGumpID); AddLabelCropped(x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, TextHue, type.Name); x += TypeWidth + OffsetSize; if (SetGumpID != 0) { AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID); } } else if (o is PropertyInfo) { PropertyInfo prop = (PropertyInfo)o; AddImageTiled(x, y, NameWidth, EntryHeight, EntryGumpID); AddLabelCropped(x + TextOffsetX, y, NameWidth - TextOffsetX, EntryHeight, TextHue, prop.Name); x += NameWidth + OffsetSize; AddImageTiled(x, y, ValueWidth, EntryHeight, EntryGumpID); AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, TextHue, ValueToString(prop)); x += ValueWidth + OffsetSize; if (SetGumpID != 0) { AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID); } CPA cpa = GetCPA(prop); if (prop.CanWrite && cpa != null && m_Mobile.AccessLevel >= cpa.WriteLevel && !cpa.ReadOnly) { AddButton(x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 3, GumpButtonType.Reply, 0); } } else { AddImageTiled(x - OffsetSize, y, TotalWidth, EntryHeight, BackGumpID + 4); } } }
public override void OnResponse(NetState state, RelayInfo info) { Mobile from = state.Mobile; if (!BaseCommand.IsAccessible(from, m_Object)) { from.SendMessage("You may no longer access their properties."); return; } switch (info.ButtonID) { case 0: // Closed { if (m_Stack != null && m_Stack.Count > 0) { StackEntry entry = (StackEntry)m_Stack.Pop(); from.SendGump(new PropertiesGump(from, entry.m_Object, m_Stack, null)); } } break; case 1: // Previous { if (m_Page > 0) { from.SendGump(new PropertiesGump(from, m_Object, m_Stack, m_List, m_Page - 1)); } } break; case 2: // Next { if ((m_Page + 1) * EntryCount < m_List.Count) { from.SendGump(new PropertiesGump(from, m_Object, m_Stack, m_List, m_Page + 1)); } } break; default: { int index = (m_Page * EntryCount) + (info.ButtonID - 3); if (index >= 0 && index < m_List.Count) { PropertyInfo prop = m_List[index] as PropertyInfo; if (prop == null) { return; } CPA attr = GetCPA(prop); if (!prop.CanWrite || attr == null || from.AccessLevel < attr.WriteLevel || attr.ReadOnly) { return; } Type type = prop.PropertyType; if (IsType(type, _TypeOfMobile) || IsType(type, _TypeOfItem) || type.IsAssignableFrom(typeof(IDamageable))) { from.SendGump(new SetObjectGump(prop, from, m_Object, m_Stack, type, m_Page, m_List)); } else if (IsType(type, _TypeOfType)) { from.Target = new SetObjectTarget(prop, from, m_Object, m_Stack, type, m_Page, m_List); } else if (IsType(type, _TypeOfPoint3D)) { from.SendGump(new SetPoint3DGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, _TypeOfPoint2D)) { from.SendGump(new SetPoint2DGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, _TypeOfTimeSpan)) { from.SendGump(new SetTimeSpanGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsCustomEnum(type)) { from.SendGump(new SetCustomEnumGump(prop, from, m_Object, m_Stack, m_Page, m_List, GetCustomEnumNames(type))); } else if (_TypeOfIDynamicEnum.IsAssignableFrom(type)) { from.SendGump( new SetCustomEnumGump( prop, from, m_Object, m_Stack, m_Page, m_List, ((IDynamicEnum)prop.GetValue(m_Object, null)).Values)); } else if (IsType(type, _TypeOfEnum)) { from.SendGump( new SetListOptionGump( prop, from, m_Object, m_Stack, m_Page, m_List, Enum.GetNames(type), GetObjects(Enum.GetValues(type)))); } else if (IsType(type, _TypeOfBool)) { from.SendGump(new SetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_BoolNames, m_BoolValues)); } else if (IsType(type, _TypeOfString) || IsType(type, _TypeOfReal) || IsType(type, _TypeOfNumeric) || IsType(type, _TypeOfText)) { from.SendGump(new SetGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, _TypeOfPoison)) { from.SendGump( new SetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_PoisonNames, m_PoisonValues)); } else if (IsType(type, _TypeofDateTime)) { from.SendGump(new SetDateTimeGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, _TypeOfMap)) { //Must explicitly cast collection to avoid potential covariant cast runtime exception object[] values = Map.GetMapValues().Cast <object>().ToArray(); from.SendGump(new SetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, Map.GetMapNames(), values)); } else if (IsType(type, _TypeOfSkills) && m_Object is Mobile) { from.SendGump(new PropertiesGump(from, m_Object, m_Stack, m_List, m_Page)); from.SendGump(new SkillsGump(from, (Mobile)m_Object)); } else if (IsType(type, _TypeofColor)) { from.SendGump(new SetColorGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, _TypeofAccount)) { from.SendGump(new PropertiesGump(from, m_Object, m_Stack, m_List, m_Page)); } else if (HasAttribute(type, _TypeOfPropertyObject, true)) { object obj = prop.GetValue(m_Object, null); from.SendGump( obj != null ? new PropertiesGump(from, obj, m_Stack, new StackEntry(m_Object, prop)) : new PropertiesGump(from, m_Object, m_Stack, m_List, m_Page)); } } } break; } }
public override void OnResponse(NetState state, RelayInfo info) { Mobile from = state.Mobile; if (!BaseCommand.IsAccessible(from, m_Object)) { from.SendMessage("You may no longer access their properties."); return; } switch (info.ButtonID) { case 0: // Closed { if (m_Stack != null && m_Stack.Count > 0) { #if (NEWTIMERS) PropertiesGump.StackEntry entry = m_Stack.Pop(); from.SendGump(new XmlPropertiesGump(from, entry.m_Object, m_Stack, null)); #else object obj = m_Stack.Pop(); from.SendGump(new XmlPropertiesGump(from, obj, m_Stack, null)); #endif } break; } case 1: // Previous { if (m_Page > 0) { from.SendGump(new XmlPropertiesGump(from, m_Object, m_Stack, m_List, m_Page - 1)); } break; } case 2: // Next { if ((m_Page + 1) * EntryCount < m_List.Count) { from.SendGump(new XmlPropertiesGump(from, m_Object, m_Stack, m_List, m_Page + 1)); } break; } default: { int index = (m_Page * EntryCount) + (info.ButtonID - 3); if (index >= 0 && index < m_List.Count) { PropertyInfo prop = m_List[index] as PropertyInfo; if (prop == null) { return; } CPA attr = GetCPA(prop); if (!prop.CanWrite || attr == null || from.AccessLevel < attr.WriteLevel) { return; } Type type = prop.PropertyType; if (IsType(type, typeofMobile) || IsType(type, typeofItem)) { from.SendGump(new XmlSetObjectGump(prop, from, m_Object, m_Stack, type, m_Page, m_List)); } else if (IsType(type, typeofType)) { from.Target = new XmlSetObjectTarget(prop, from, m_Object, m_Stack, type, m_Page, m_List); } else if (IsType(type, typeofPoint3D)) { from.SendGump(new XmlSetPoint3DGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, typeofPoint2D)) { from.SendGump(new XmlSetPoint2DGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, typeofTimeSpan)) { from.SendGump(new XmlSetTimeSpanGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsCustomEnum(type)) { from.SendGump(new XmlSetCustomEnumGump(prop, from, m_Object, m_Stack, m_Page, m_List, GetCustomEnumNames(type))); } else if (IsType(type, typeofEnum)) { from.SendGump(new XmlSetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, Enum.GetNames(type), GetObjects(Enum.GetValues(type)))); } else if (IsType(type, typeofBool)) { from.SendGump(new XmlSetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_BoolNames, m_BoolValues)); } else if (IsType(type, typeofString) || IsType(type, typeofReal) || IsType(type, typeofNumeric)) { from.SendGump(new XmlSetGump(prop, from, m_Object, m_Stack, m_Page, m_List)); } else if (IsType(type, typeofPoison)) { from.SendGump(new XmlSetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_PoisonNames, m_PoisonValues)); } else if (IsType(type, typeofMap)) { from.SendGump(new XmlSetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, Map.GetMapNames(), Map.GetMapValues())); } else if (IsType(type, typeofSkills) && m_Object is Mobile mobile) { from.SendGump(new XmlPropertiesGump(from, mobile, m_Stack, m_List, m_Page)); from.SendGump(new SkillsGump(from, mobile)); } else if (HasAttribute(type, typeofPropertyObject, true)) { #if (NEWTIMERS) object obj = prop.GetValue(m_Object, null); from.SendGump(obj != null ? new XmlPropertiesGump(from, obj, m_Stack, new PropertiesGump.StackEntry(m_Object, prop)) : new XmlPropertiesGump(from, m_Object, m_Stack, m_List, m_Page)); #else from.SendGump(new XmlPropertiesGump(from, prop.GetValue(m_Object, null), m_Stack, m_Object)); #endif } } break; } } }
private void Initialize(int page) { m_Page = page; int count = m_List.Count - (page * EntryCount); if (count < 0) { count = 0; } else if (count > EntryCount) { count = EntryCount; } int lastIndex = (page * EntryCount) + count - 1; if (lastIndex >= 0 && lastIndex < m_List.Count && m_List[lastIndex] == null) { --count; } int totalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (ColumnEntryCount + 1)); AddPage(0); AddBackground(0, 0, TotalWidth * 3 + BorderSize * 2, BorderSize + totalHeight + BorderSize, BackGumpID); AddImageTiled(BorderSize, BorderSize + EntryHeight, (TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0)) * 3, totalHeight - EntryHeight, OffsetGumpID); int x = BorderSize + OffsetSize; int y = BorderSize; if (m_Object is Item item) { AddLabelCropped(x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, TextHue, item.Name); } int propcount = 0; for (int i = 0, index = page * EntryCount; i <= count && index < m_List.Count; ++i, ++index) { // do the multi column display int column = propcount / ColumnEntryCount; if (propcount % ColumnEntryCount == 0) { y = BorderSize; } x = BorderSize + OffsetSize + column * (ValueWidth + NameWidth + OffsetSize * 2 + SetOffsetX + SetWidth); y += EntryHeight + OffsetSize; object o = m_List[index]; if (o == null) { AddImageTiled(x - OffsetSize, y, TotalWidth, EntryHeight, BackGumpID + 4); propcount++; } else if (o is PropertyInfo prop) { propcount++; // look for the default value of the equivalent property in the XmlSpawnerDefaults.DefaultEntry class int huemodifier = TextHue; Mobiles.XmlSpawnerDefaults.DefaultEntry de = new Mobiles.XmlSpawnerDefaults.DefaultEntry(); Type ftype = de.GetType(); var finfo = ftype.GetField(prop.Name); // is there an equivalent default field? if (finfo != null) { // see if the value is different from the default if (ValueToString(finfo.GetValue(de)) != ValueToString(prop)) { huemodifier = 68; } } AddImageTiled(x, y, NameWidth, EntryHeight, EntryGumpID); AddLabelCropped(x + TextOffsetX, y, NameWidth - TextOffsetX, EntryHeight, huemodifier, prop.Name); x += NameWidth + OffsetSize; AddImageTiled(x, y, ValueWidth, EntryHeight, EntryGumpID); AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, huemodifier, ValueToString(prop)); x += ValueWidth + OffsetSize; if (SetGumpID != 0) { AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID); } CPA cpa = GetCPA(prop); if (prop.CanWrite && cpa != null && m_Mobile.AccessLevel >= cpa.WriteLevel) { AddButton(x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 3, GumpButtonType.Reply, 0); } } } }
public static int BuildObjects(Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props, List <Container> packs, bool outline = false, bool mapAvg = false) { Utility.FixPoints(ref start, ref end); PropertyInfo[] realProps = null; if (props != null) { realProps = new PropertyInfo[props.GetLength(0)]; PropertyInfo[] allProps = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); for (int i = 0; i < realProps.Length; ++i) { PropertyInfo thisProp = null; string propName = props[i, 0]; for (int j = 0; thisProp == null && j < allProps.Length; ++j) { if (Insensitive.Equals(propName, allProps[j].Name)) { thisProp = allProps[j]; } } if (thisProp == null) { from.SendMessage("Property not found: {0}", propName); } else { CPA attr = Properties.GetCPA(thisProp); if (attr == null) { from.SendMessage("Property ({0}) not found.", propName); } else if (from.AccessLevel < attr.WriteLevel) { from.SendMessage("Setting this property ({0}) requires at least {1} access level.", propName, Mobile.GetAccessLevelName(attr.WriteLevel)); } else if (!thisProp.CanWrite || attr.ReadOnly) { from.SendMessage("Property ({0}) is read only.", propName); } else { realProps[i] = thisProp; } } } } ConstructorInfo[] ctors = type.GetConstructors(); for (int i = 0; i < ctors.Length; ++i) { ConstructorInfo ctor = ctors[i]; if (!IsConstructible(ctor, from.AccessLevel)) { continue; } int totalParams = 0; // Handle optional constructors ParameterInfo[] paramList = ctor.GetParameters(); for (int j = 0; j < paramList.Length; j++) { if (!paramList[j].HasDefaultValue) { totalParams += 1; } } if (args.Length >= totalParams && args.Length <= paramList.Length) { object[] paramValues = ParseValues(paramList, args); if (paramValues == null) { continue; } int built = Build(from, start, end, ctor, paramValues, props, realProps, packs, outline, mapAvg); if (built > 0) { return(built); } } } return(0); }