Example #1
0
        // These functions are borrowed heavily from ArteGordon's BaseXmlSpawner class

        // set property values with support for nested attributes
        public static void SetPropertyValue(TriggerObject trigObj, object o, string name, object value)
        {
            if (o == null)
            {
                throw new UberScriptException("Null object");
            }

            //Type ptype = null;
            object po   = null;
            Type   type = o.GetType();

            PropertyInfo[] props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);

            // parse the strings of the form property.attribute into two parts
            // first get the property
            List <string> arglist = PropertyGetters.PropSplitter(name);

            string propname = arglist[0];

            if (propname.Length == 0)
            {
                throw new UberScriptException("Empty string property!");
            }

            // Check whether they are trying to set an xml attachment through the
            // shortcut e.g. TRIGMOB().xmlints.score = TRIGMOB().xmlints.score + 1

            if (arglist.Count > 1 && (propname[0] == 'x' || propname[0] == 'X'))
            {
                // NEED TO HANDLE SETTING PROPERTIES ON THE ATTACHMENTS!
                string lowerPropName = propname.ToLower();
                if (lowerPropName == "xmlints")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlints on anything but Mobile or Item");
                    }
                    // check for existing xmlValue attachment or create a new one
                    XmlValue xmlValue = XmlAttach.GetValueAttachment(entity, arglist[1]);
                    if (xmlValue == null)
                    {
                        // arglist should only have [xmlints, name], nothing more
                        if (arglist.Count > 2)
                        {
                            throw new UberScriptException("Attempted to set property on a not-yet-existant attachment!:" + name);
                        }
                        xmlValue = new XmlValue(arglist[1], (int)value);
                        XmlAttach.AttachTo(null, entity, xmlValue);
                    }
                    else if (arglist.Count == 2)
                    {
                        if (value == null)
                        {
                            xmlValue.Delete();
                        }
                        else
                        {
                            xmlValue.Value = (int)value;
                        }
                    }
                    else if (arglist.Count > 2)
                    {
                        // could be setting a property on an existing XmlAttachment!
                        // e.g. xmlints.test.expiration = 0:0:1
                        SetPropertyValue(trigObj, xmlValue, arglist[2], value);
                    }
                    return;
                }
                else if (lowerPropName == "xmlstrings")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlstrings on anything but Mobile or Item");
                    }
                    XmlLocalVariable xmlLocalVariable = XmlAttach.GetStringAttachment(entity, arglist[1]);
                    if (xmlLocalVariable == null)
                    {
                        // arglist should only have [xmlints, name], nothing more
                        if (arglist.Count > 2)
                        {
                            throw new UberScriptException("Attempted to set property on a not-yet-existant attachment!:" + name);
                        }
                        xmlLocalVariable = new XmlLocalVariable(arglist[1], (string)value);
                        XmlAttach.AttachTo(null, entity, xmlLocalVariable);
                    }
                    else if (arglist.Count == 2)
                    {
                        if (value == null)
                        {
                            xmlLocalVariable.Delete();
                        }
                        else
                        {
                            xmlLocalVariable.Data = (string)value;
                        }
                    }
                    else if (arglist.Count > 2)
                    {
                        // could be setting a property on an existing XmlAttachment!
                        // e.g. xmlints.test.expiration = 0:0:1
                        SetPropertyValue(trigObj, xmlLocalVariable, arglist[2], value);
                    }
                    return;
                }
                else if (lowerPropName == "xmldoubles")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmldoubles on anything but Mobile or Item");
                    }
                    XmlDouble xmlDouble = XmlAttach.GetDoubleAttachment(entity, arglist[1]);
                    if (xmlDouble == null)
                    {
                        // arglist should only have [xmlints, name], nothing more
                        if (arglist.Count > 2)
                        {
                            throw new UberScriptException("Attempted to set property on a not-yet-existant attachment!:" + name);
                        }
                        xmlDouble = new XmlDouble(arglist[1], (double)value);
                        XmlAttach.AttachTo(null, entity, xmlDouble);
                    }
                    else if (arglist.Count == 2)
                    {
                        if (value == null)
                        {
                            xmlDouble.Delete();
                        }
                        else
                        {
                            xmlDouble.Value = (double)value;
                        }
                    }
                    else if (arglist.Count > 2)
                    {
                        // could be setting a property on an existing XmlAttachment!
                        // e.g. xmlints.test.expiration = 0:0:1
                        SetPropertyValue(trigObj, xmlDouble, arglist[2], value);
                    }
                    return;
                }
                else if (lowerPropName == "xmlobjs")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlobjs on anything but Mobile or Item");
                    }
                    XmlObject xmlObject = XmlAttach.GetObjectAttachment(entity, arglist[1]);
                    if (xmlObject == null)
                    {
                        // arglist should only have [xmlints, name], nothing more
                        if (arglist.Count > 2)
                        {
                            throw new UberScriptException("Attempted to set property on a not-yet-existant attachment!:" + name);
                        }
                        xmlObject = new XmlObject(arglist[1], value);
                        XmlAttach.AttachTo(null, entity, xmlObject);
                    }
                    else if (arglist.Count == 2)
                    {
                        if (value == null)
                        {
                            xmlObject.Delete();
                        }
                        else
                        {
                            xmlObject.Value = value;
                        }
                    }
                    else if (arglist.Count > 2)
                    {
                        // XmlObject only contains a few properties that
                        // can be accessed through statements like THIS().xmlobjs.test._____
                        // since there is a potential conflict between the developer wanting access
                        // to the properties on the object contained in the XmlObject.Value (most likely)
                        // or the properties on the XmlObject itself (far less likely)
                        string testPropName = arglist[2].ToLower();
                        // to access properties on the xmlobject itself (e.g. expiration), one must do this:
                        //  THIS().xmlobjs.test.xmlobject.expiration
                        if (testPropName == "xmlobject")
                        {
                            if (arglist.Count < 4)
                            {
                                throw new UberScriptException("Can't set an xmlobject directly, use ATTACH function!");
                            }
                            else
                            {
                                string propLookup = arglist[3]; // add this first so later additions all prepended with '.'
                                for (int i = 4; i < arglist.Count; i++)
                                {
                                    propLookup += "." + arglist[i];
                                }
                                SetPropertyValue(trigObj, xmlObject, propLookup, value);
                            }
                        }
                        else
                        {
                            string propLookup = arglist[2]; // add this first so later additions all prepended with '.'
                            for (int i = 3; i < arglist.Count; i++)
                            {
                                propLookup += "." + arglist[i];
                            }
                            SetPropertyValue(trigObj, xmlObject.Value, propLookup, value);
                        }
                    }

                    //else if (arglist.Count > 2)
                    //{
                    // could be setting a property on an existing XmlAttachment!
                    // e.g. xmlints.test.expiration = 0:0:1
                    //    SetPropertyValue(trigObject, xmlObject, arglist[2], value);
                    //}
                    return;
                }
            }

            /*
             * string[] keywordargs = ParseString(propname, 4, ",");
             *
             * // check for special keywords
             * if (keywordargs[0] == "ATTACHMENT")
             * {
             *  if (keywordargs.Length < 4)
             *  {
             *      return "Invalid ATTACHMENT format";
             *  }
             *  // syntax is ATTACHMENT,type,name,propname
             *
             *  string apropname = keywordargs[3];
             *  string aname = keywordargs[2];
             *  Type attachtype = SpawnerType.GetType(keywordargs[1]);
             *
             *  // allow empty string specifications to be used to indicate a null string which will match any name
             *  if (aname == "") aname = null;
             *
             *  ArrayList attachments = XmlAttach.FindAttachments(o, attachtype, aname);
             *
             *  if (attachments != null && attachments.Count > 0)
             *  {
             *      // change the object, object type, and propname to refer to the attachment
             *      o = attachments[0];
             *      propname = apropname;
             *
             *      if (o == null)
             *      {
             *          return "Null object";
             *      }
             *
             *      type = o.GetType();
             *      props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
             *  }
             *  else
             *      return "Attachment not found";
             *
             * }
             * else if (keywordargs[0] == "SKILL")
             * {
             *  if (keywordargs.Length < 2)
             *  {
             *      return "Invalid SKILL format";
             *  }
             *  bool found = true;
             *  try
             *  {
             *      SkillName skillname = (SkillName)Enum.Parse(typeof(SkillName), keywordargs[1], true);
             *      if (o is Mobile)
             *      {
             *
             *          Skill skill = ((Mobile)o).Skills[skillname];
             *
             *          skill.Base = double.Parse(value);
             *
             *          return "Property has been set.";
             *      }
             *      else
             *          return "Object is not mobile";
             *  }
             *  catch { found = false; }
             *
             *  if (!found)
             *      return "Invalid SKILL reference.";
             * }
             * else if (keywordargs[0] == "STEALABLE")
             * {
             *
             *  bool found = true;
             *  try
             *  {
             *      if (o is Item)
             *      {
             *
             *          ItemFlags.SetStealable(o as Item, bool.Parse(value));
             *
             *          return "Property has been set.";
             *      }
             *      else
             *          return "Object is not an item";
             *  }
             *  catch { found = false; }
             *
             *  if (!found)
             *      return "Invalid Stealable assignment.";
             * }
             * */

            // do a bit of parsing to handle array references
            string[] arraystring = propname.Split('[');
            int      index       = 0;

            if (arraystring.Length > 1)
            {
                // parse the property name from the indexing
                propname = arraystring[0];

                // then parse to get the index value
                string[] arrayvalue = arraystring[1].Split(']');

                if (arrayvalue.Length > 0)
                {
                    try
                    {
                        index = int.Parse(arrayvalue[0]);
                    }
                    catch
                    {
                        try
                        {
                            index = (int)(new MathTree(null, arrayvalue[0])).Calculate(trigObj);
                        }
                        catch
                        {
                            throw new UberScriptException("Could not get int array value from: " + arrayvalue[0] + " for prop of " + name + " on object " + o);
                        }
                    }
                }
            }
            PropertyInfo propInfoToSet     = null;
            string       lowerCasePropName = propname.ToLower();

            // optimization to find propertyInfo without looping through
            if (o is BaseCreature)
            {
                if (BaseCreatureProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToSet = BaseCreatureProperties[lowerCasePropName];
                }
            }
            else if (o is PlayerMobile)
            {
                if (PlayerMobileProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToSet = PlayerMobileProperties[lowerCasePropName];
                }
            }
            else if (o is Item)
            {
                if (ItemProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToSet = ItemProperties[lowerCasePropName];
                }
            }
            // is a nested property with attributes so first get the property
            if (propInfoToSet == null)
            {
                foreach (PropertyInfo p in props)
                {
                    if (Insensitive.Equals(p.Name, propname))
                    {
                        propInfoToSet = p;
                        break;
                    }
                }
            }
            if (propInfoToSet != null)
            {
                //if (IsProtected(type, propname))
                //    return "Property is protected.";

                if (arglist.Count > 1)
                {
                    //ptype = propInfoToSet.PropertyType;
                    po = propInfoToSet.GetValue(o, null);
                    // now set the nested attribute using the new property list
                    string propLookup = arglist[1];
                    for (int i = 2; i < arglist.Count; i++)
                    {
                        propLookup += "." + arglist[i];
                    }
                    SetPropertyValue(trigObj, po, propLookup, value);
                    return;
                    // otherwise let it roll through and throw an exception
                }
                else // arglist.Count == 1
                {
                    //if (IsProtected(type, propname))
                    //    return "Property is protected.";
                    if (!propInfoToSet.CanWrite)
                    {
                        throw new UberScriptException("Property is read only.");
                    }

                    InternalSetValue(o, propInfoToSet, value, false, index);
                    return;
                }
            }

            throw new UberScriptException("Property " + name + " not found on " + o + ".");
        }
Example #2
0
        public static object GetObject(TriggerObject trigObj, object o, string name, out Type ptype) // used for all comparisons
        {
            // ALL EXCEPTIONS CAUGHT OUTSIDE OF THIS FUNCTION (so that a useful error can be displayed)
            // trigobject used in case there are array indeces with a function [THIS().x]
            ptype = null;
            if (o == null || name == null)
            {
                return(null);
            }

            Type   type = o.GetType();
            object po   = null;

            PropertyInfo[] props = null;
            try
            {
                props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
            }
            catch (Exception e)
            {
                throw new UberScriptException("GetProperties Error!", e);
            }

            // parse the strings of the form property.attribute into two parts
            // first get the property
            List <string> arglist  = PropSplitter(name);
            string        propname = arglist[0];

            if (propname.Length == 0)
            {
                throw new UberScriptException("Empty string property!");
            }
            if (arglist.Count > 1 && (propname[0] == 'x' || propname[0] == 'X'))
            {
                if (propname.ToLower() == "xmlints")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlints on anything but Mobile or Item");
                    }
                    // check for existing xmlValue attachment or create a new one
                    XmlValue xmlValue = XmlAttach.GetValueAttachment(o as IEntity, arglist[1]);
                    if (xmlValue == null)
                    {
                        return(null);      //throw new UberScriptException("Could not find XmlValue named " + name + " on " + o);
                    }
                    if (arglist.Count > 2) // must be trying to get a property on the xmlValue (e.g. xmlints.test.expiration)
                    {
                        return(GetObject(trigObj, xmlValue, arglist[2], out ptype));
                    }
                    ptype = typeof(int);
                    return(xmlValue.Value);
                }
                else if (propname.ToLower() == "xmlstrings")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlstrings on anything but Mobile or Item");
                    }
                    XmlLocalVariable xmlLocalVariable = XmlAttach.GetStringAttachment(o as IEntity, arglist[1]);
                    if (xmlLocalVariable == null)
                    {
                        return(null);      // throw new UberScriptException("Could not find XmlLocalVariable named " + name + " on " + o);
                    }
                    if (arglist.Count > 2) // must be trying to get a property on the xmlValue (e.g. xmlints.test.expiration)
                    {
                        return(GetObject(trigObj, xmlLocalVariable, arglist[2], out ptype));
                    }
                    ptype = typeof(string);
                    return(xmlLocalVariable.Data);
                }
                else if (propname.ToLower() == "xmldoubles")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmldoubles on anything but Mobile or Item");
                    }
                    XmlDouble xmlDouble = XmlAttach.GetDoubleAttachment(entity, arglist[1]);
                    if (xmlDouble == null)
                    {
                        return(null);      //  throw new UberScriptException("Could not find XmlDouble named " + name + " on " + o);
                    }
                    if (arglist.Count > 2) // must be trying to get a property on the xmlValue (e.g. xmlints.test.expiration)
                    {
                        return(GetObject(trigObj, xmlDouble, arglist[2], out ptype));
                    }
                    ptype = typeof(double);
                    return(xmlDouble.Value);
                }
                else if (propname.ToLower() == "xmlobjs")
                {
                    IEntity entity = o as IEntity;
                    if (entity == null)
                    {
                        throw new UberScriptException("Can't set xmlobjs on anything but Mobile or Item");
                    }
                    // since the object might be a list of some kind, need to check for the [] indexing first
                    string objName          = arglist[1];
                    int    openBracketIndex = objName.IndexOf('[');
                    int    listindex        = -1; // for lists / arrays
                    if (openBracketIndex > 0)
                    {
                        int closingBracketIndex = objName.IndexOf(']');
                        if (closingBracketIndex < openBracketIndex + 1)
                        {
                            throw new UberScriptException("xmlobjs." + objName + " [] indexing error: must have at least 1 character between the []");
                        }

                        listindex = (int)(new MathTree(null, objName.Substring(openBracketIndex + 1, closingBracketIndex - openBracketIndex - 1))).Calculate(trigObj);
                        objName   = objName.Substring(0, openBracketIndex);
                    }

                    XmlObject xmlObject = XmlAttach.GetObjectAttachment(entity, objName);
                    if (xmlObject == null)
                    {
                        return(null);                   // throw new UberScriptException("Could not find XmlObject named " + name + " on " + o);
                    }
                    //if (arglist.Count > 2) // must be trying to get a property on the xmlValue (e.g. xmlints.test.expiration)
                    //    return GetObject(trigObject, xmlObject, arglist[2], out ptype);


                    //=====
                    if (arglist.Count > 2)
                    {
                        // XmlObject only contains a few properties that
                        // can be accessed through statements like THIS().xmlobjs.test._____
                        // since there is a potential conflict between the developer wanting access
                        // to the properties on the object contained in the XmlObject.Value (most likely)
                        // or the properties on the XmlObject itself (far less likely)
                        string testPropName = arglist[2].ToLower();
                        // to access properties on the xmlobject itself (e.g. expiration), one must do this:
                        //  THIS().xmlobjs.test.xmlobject.expiration
                        if (testPropName == "xmlobject")
                        {
                            if (arglist.Count < 4)
                            {
                                return(xmlObject);
                            }

                            string propLookup = arglist[3]; // add this first so later additions all prepended with '.'
                            for (int i = 4; i < arglist.Count; i++)
                            {
                                propLookup += "." + arglist[i];
                            }
                            return(PropertyGetters.GetObject(trigObj, xmlObject, propLookup, out ptype));
                        }
                        else
                        {
                            if (xmlObject.Value == null)
                            {
                                return(null);
                            }
                            string propLookup = arglist[2]; // add this first so later additions all prepended with '.'
                            for (int i = 3; i < arglist.Count; i++)
                            {
                                propLookup += "." + arglist[i];
                            }

                            if (listindex >= 0)
                            {
                                ptype = xmlObject.Value.GetType();
                                if (ptype.GetInterface("IList") != null)
                                {
                                    try
                                    {
                                        return(PropertyGetters.GetObject(trigObj, ((IList)xmlObject.Value)[listindex], propLookup, out ptype));
                                        //return ((IList)xmlObject.Value)[listindex];
                                    }
                                    catch (Exception e)
                                    {
                                        throw new UberScriptException("Get Array value error!", e);
                                    }
                                }
                                else
                                {
                                    throw new UberScriptException("xmlobj." + objName + " was indexed with [] indexer, but did not contain a list!");
                                }
                            }

                            return(PropertyGetters.GetObject(trigObj, xmlObject.Value, propLookup, out ptype));
                        }
                    }
                    else if (listindex >= 0)
                    {
                        // no properties afterward but has a list index (e.g. xmlobjs.spawnedPlatforms[0])
                        ptype = xmlObject.Value.GetType();
                        if (ptype.GetInterface("IList") != null)
                        {
                            try
                            {
                                return(((IList)xmlObject.Value)[listindex]);
                            }
                            catch (Exception e)
                            {
                                throw new UberScriptException("Get Array value error!", e);
                            }
                        }
                        else
                        {
                            throw new UberScriptException("xmlobj." + objName + " was indexed with [] indexer, but did not contain a list!");
                        }
                    }
                    //====


                    ptype = typeof(object);
                    return(xmlObject.Value);
                }
            }
            // parse up to 4 comma separated args for special keyword properties

            /*
             * string[] keywordargs = ParseString(propname, 4, ",");
             *
             * // check for special keywords
             * if (keywordargs[0] == "ATTACHMENT")
             * {
             *  // syntax is ATTACHMENT,type,name,property
             *  if (keywordargs.Length < 4)
             *  {
             *      return "Invalid ATTACHMENT format";
             *  }
             *
             *  string apropname = keywordargs[3];
             *  string aname = keywordargs[2];
             *  Type attachtype = SpawnerType.GetType(keywordargs[1]);
             *
             *  // allow empty string specifications to be used to indicate a null string which will match any name
             *  if (aname == "") aname = null;
             *
             *  ArrayList attachments = XmlAttach.FindAttachments(o, attachtype, aname);
             *
             *  if (attachments != null && attachments.Count > 0)
             *  {
             *      string getvalue = GetPropertyValue(spawner, attachments[0], apropname, out ptype);
             *
             *      return getvalue;
             *  }
             *  else
             *      return "Attachment not found";
             * }
             * */

            // I REALLY OUGHT TO IMPLEMENT GETTING TYPE SOME TIME
            // do a bit of parsing to handle array references
            string[] arraystring = arglist[0].Split('[');
            int      index       = -1;

            if (arraystring.Length > 1)
            {
                // parse the property name from the indexing
                propname = arraystring[0];

                // then parse to get the index value
                string[] arrayvalue = arraystring[1].Split(']');

                if (arrayvalue.Length > 0)
                {
                    try
                    {
                        index = int.Parse(arrayvalue[0]);
                    }
                    catch
                    {
                        try
                        {
                            index = (int)(new MathTree(null, arrayvalue[0])).Calculate(trigObj);
                        }
                        catch
                        {
                            throw new UberScriptException("Could not get int array value from: " + arrayvalue[0] + " for prop of " + name + " on object " + o);
                        }
                    }
                }
            }

            PropertyInfo propInfoToGet     = null;
            string       lowerCasePropName = propname.ToLower();

            // optimization to find propertyInfo without looping through
            if (o is BaseCreature)
            {
                if (PropertySetters.BaseCreatureProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToGet = PropertySetters.BaseCreatureProperties[lowerCasePropName];
                }
            }
            else if (o is PlayerMobile)
            {
                if (PropertySetters.PlayerMobileProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToGet = PropertySetters.PlayerMobileProperties[lowerCasePropName];
                }
            }
            else if (o is Item)
            {
                if (PropertySetters.ItemProperties.ContainsKey(lowerCasePropName))
                {
                    propInfoToGet = PropertySetters.ItemProperties[lowerCasePropName];
                }
            }
            // is a nested property with attributes so first get the property
            if (propInfoToGet == null)
            {
                foreach (PropertyInfo p in props)
                {
                    if (Insensitive.Equals(p.Name, propname))
                    {
                        propInfoToGet = p;
                        break;
                    }
                }
            }
            if (propInfoToGet != null)
            {
                if (!propInfoToGet.CanRead)
                {
                    throw new UberScriptException("Property " + propname + " is write only.");
                }
                //if (IsProtected(type, propname))
                //    return "Property is protected.";
                ptype = propInfoToGet.PropertyType;
                if (arglist.Count > 1)
                {
                    if (ptype.IsPrimitive)
                    {
                        po = propInfoToGet.GetValue(o, null);
                    }
                    else if ((ptype.GetInterface("IList") != null) && index >= 0)
                    {
                        try
                        {
                            object arrayvalue = propInfoToGet.GetValue(o, null);
                            po = ((IList)arrayvalue)[index];
                        }
                        catch (Exception e)
                        {
                            throw new UberScriptException("Get Array value error!", e);
                        }
                    }
                    else
                    {
                        po = propInfoToGet.GetValue(o, null);
                    }
                    // now set the nested attribute using the new property list
                    string propLookup = arglist[1];
                    for (int i = 2; i < arglist.Count; i++)
                    {
                        propLookup += "." + arglist[i];
                    }
                    return(GetObject(trigObj, po, propLookup, out ptype));
                }
                else
                {
                    // its just a simple single property
                    return(InternalGetValue(o, propInfoToGet, index));
                }
            }

            throw new UberScriptException("Could not find property on " + o + ": " + name);
        }