Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        public IEntity Dupe()
        {
            MemoryStream stream = new MemoryStream();
            DupeWriter   writer = new DupeWriter(stream, this);
            DupeReader   reader = new DupeReader(stream, this);

            try
            {
                m_From.SendMessage("Objects Found: {0}", m_Entities.Count);
                foreach (IEntity entity in m_Entities)
                {                 //We add it at the same time we serialize, makes for less looping
                    IEntity newent = AddEntity(entity.GetType());

                    m_NewEntities.Add(newent);

                    if (entity is Item)
                    {
                        ((Item)entity).Serialize(writer);
                    }
                    else                     //Its a mob!
                    {
                        ((Mobile)entity).Serialize(writer);
                    }
                }

                writer.Flush();
                reader.Seek(0, SeekOrigin.Begin);

                for (int i = 0; i < m_NewEntities.Count; i++)
                {
                    IEntity entity = m_NewEntities[i];

                    if (entity is Item)
                    {
                        ((Item)entity).Deserialize(reader);
                    }
                    else                     //Its a mob!
                    {
                        ((Mobile)entity).Deserialize(reader);
                    }
                }

                if (!reader.End())
                {
                    m_From.SendMessage("The buffer is not empty.  There was an error in deserialization.");
                    return(null);
                }
            }
            catch (Exception e)
            {
                m_From.SendMessage(e.Message);
                Console.WriteLine(e);

                for (int i = m_NewEntities.Count - 1; i >= 0; i--)
                {
                    m_NewEntities[i].Delete();
                }

                m_NewEntities.Clear();
            }
            finally
            {
                writer.Close();
                reader.Close();
                stream.Close();
            }

            if (m_NewEntities.Count > 0)
            {
                return(m_NewEntities[0]);
            }
            else
            {
                m_From.SendMessage("Error duping objects.  No objects duped.");
                return(null);
            }
        }