Beispiel #1
0
        static CallbackResult OnUpdateStats(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                if (data[0] != 0x2D)
                {
                    throw new Exception("Invalid packet passed to OnUpdateStats.");
                }

                uint serial = ByteConverter.BigEndian.ToUInt32(data, 1);

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null)
                {
                    Trace.WriteLine(String.Format("Cannot update stats for unknown character (serial=0x{0}).", serial.ToString("X8")), "World");
                    return(CallbackResult.Normal);
                }

                chr.MaxHits    = ByteConverter.BigEndian.ToInt16(data, 5);
                chr.Hits       = ByteConverter.BigEndian.ToInt16(data, 7);
                chr.MaxMana    = ByteConverter.BigEndian.ToInt16(data, 9);
                chr.Mana       = ByteConverter.BigEndian.ToInt16(data, 11);
                chr.MaxStamina = ByteConverter.BigEndian.ToInt16(data, 13);
                chr.Stamina    = ByteConverter.BigEndian.ToInt16(data, 15);

                ObjectChanged(serial, ObjectChangeType.CharUpdated);
                return(CallbackResult.Normal);
            }
        }
Beispiel #2
0
        static CallbackResult OnCharacterStatus(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                PacketReader reader = new PacketReader(data);

                if (reader.ReadByte() != 0x11)
                {
                    throw new Exception("Invalid packet passed to OnCharacterStatus.");
                }

                ushort blockSize = reader.ReadUInt16();
                if (data.Length != blockSize)
                {
                    Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x11 doesn't meet data lenght ({1}).", blockSize, data.Length), "World");
                }

                uint serial = reader.ReadUInt32();

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null)
                {
                    Trace.WriteLine(String.Format("Cannot update status for unknown character (serial=0x{0:X8}).", serial), "World");
                    return(CallbackResult.Normal);
                }

                chr.Name      = reader.ReadAnsiString(30);
                chr.Hits      = reader.ReadInt16();
                chr.MaxHits   = reader.ReadInt16();
                chr.Renamable = reader.ReadByte() > 0;

                byte more = reader.ReadByte();

                if (more > 0)
                {
                    byte gender = reader.ReadByte();
                    chr.Strenght     = reader.ReadInt16();
                    chr.Dexterity    = reader.ReadInt16();
                    chr.Intelligence = reader.ReadInt16();
                    chr.Stamina      = reader.ReadInt16();
                    chr.MaxStamina   = reader.ReadInt16();
                    chr.Mana         = reader.ReadInt16();
                    chr.MaxMana      = reader.ReadInt16();
                    chr.Gold         = reader.ReadInt32();
                    chr.Armor        = reader.ReadUInt16();
                    chr.Weight       = reader.ReadUInt16();
                }

#if WORLDDEBUG
                Trace.WriteLine(String.Format("Character status updated ({0}).", chr.Description), "World");
#endif

                ObjectChanged(serial, ObjectChangeType.CharUpdated, true);
                return(CallbackResult.Normal);
            }
        }
Beispiel #3
0
        internal void Detach()
        {
            RealCharacter chr = World.FindRealCharacter(Container);

            if (chr != null)
            {
                chr.Layers[Layer] = 0;
                Layer             = 0;
                Container         = 0;
            }
        }
Beispiel #4
0
 /// <summary>
 /// Never returns null.
 /// </summary>
 internal static RealCharacter GetRealCharacter(uint serial)
 {
     lock (World.SyncRoot) {
         RealCharacter obj = FindRealCharacter(serial);
         if (obj != null)
         {
             return(obj);
         }
         else
         {
             return(invalidCharacter);
         }
     }
 }
Beispiel #5
0
        internal static void Add(RealCharacter character)
        {
            lock (World.SyncRoot) {
                if (character == null)
                {
                    throw new ArgumentNullException("character");
                }
                if (itemList.ContainsKey(character.Serial))
                {
                    throw new InternalErrorException("Serial already exists.");
                }

                charList.Add(character.Serial, character);
            }
        }
Beispiel #6
0
        static CallbackResult OnLoginConfirm(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                if (data[0] != 0x1B)
                {
                    throw new Exception("Invalid packet passed to OnLoginConfirm.");
                }

                bool expected = (World.PlayerSerial == World.InvalidSerial);
                uint serial   = ByteConverter.BigEndian.ToUInt32(data, 1);

                if (!expected && World.PlayerSerial != serial)
                {
                    Trace.WriteLine("Invalid serial in LoginConfirm! Packet ignored.", "World");
                    return(CallbackResult.Normal);
                }

                World.PlayerSerial = serial;

                RealCharacter chr = World.FindRealCharacter(World.PlayerSerial);
                if (chr == null)
                {
                    chr = new RealCharacter(World.PlayerSerial);
                    World.Add(chr);
                }

                chr.Graphic = ByteConverter.BigEndian.ToUInt16(data, 9);

                chr.X = ByteConverter.BigEndian.ToUInt16(data, 11);
                chr.Y = ByteConverter.BigEndian.ToUInt16(data, 13);
                chr.Z = ByteConverter.BigEndian.ToSByte(data, 16);

                chr.Direction = ByteConverter.BigEndian.ToByte(data, 17);

                WalkHandling.ClearStack();

                if (expected)
                {
                    Trace.WriteLine(String.Format("Player logged in. ({0}).", chr), "World");
                }
                else
                {
                    Trace.WriteLine("Unexpected LoginConfirm packet.", "World");
                }

                return(CallbackResult.Normal);
            }
        }
Beispiel #7
0
        static CallbackResult OnCharacterAddItem(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                if (data[0] != 0x2E)
                {
                    throw new Exception("Invalid packet passed to OnCharacterAddItem.");
                }

                uint serial = ByteConverter.BigEndian.ToUInt32(data, 1);

                bool     isNew = false;
                RealItem item  = World.FindRealItem(serial);
                if (item == null)
                {
                    item = new RealItem(serial);
                    World.Add(item);
                    isNew = true;
                }

                item.Detach();

                item.Graphic = ByteConverter.BigEndian.ToUInt16(data, 5);
                item.Layer   = ByteConverter.BigEndian.ToByte(data, 8);
                item.Color   = ByteConverter.BigEndian.ToUInt16(data, 13);

                item.Container = ByteConverter.BigEndian.ToUInt32(data, 9);

                RealCharacter chr = World.FindRealCharacter(item.Container);
                if (chr != null)
                {
                    chr.Layers[item.Layer] = item.Serial;
                }

#if WORLDDEBUG
                Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World");
#endif
                if (isNew)
                {
                    itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem));
                }

                itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.ItemUpdated));
                ObjectChanged(serial, ObjectChangeType.ItemUpdated);

                return(CallbackResult.Normal);
            }
        }
Beispiel #8
0
        static CallbackResult OnCharacterUpdate(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                PacketReader reader = new PacketReader(data);

                if (reader.ReadByte() != 0x77)
                {
                    throw new Exception("Invalid packet passed to OnCharacterUpdate.");
                }

                bool newCharacter = false;
                uint serial       = reader.ReadUInt32();

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null)
                {
                    chr = new RealCharacter(serial);
                    World.Add(chr);
                    newCharacter = true;
                }

                chr.Graphic = reader.ReadUInt16();
                chr.X       = reader.ReadUInt16();
                chr.Y       = reader.ReadUInt16();
                chr.Z       = reader.ReadSByte();

                chr.Direction = reader.ReadByte();
                chr.Color     = reader.ReadUInt16();
                chr.Flags     = reader.ReadByte();
                chr.Notoriety = reader.ReadByte();

#if WORLDDEBUG
                Debug.WriteLine(String.Format("Character updated ({0}).", chr.Description), "World");
#endif

                if (newCharacter)
                {
                    characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial));
                }

                ObjectChanged(serial, ObjectChangeType.CharUpdated);
                return(CallbackResult.Normal);
            }
        }
        static CallbackResult OnLoginConfirm(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                if (data[0] != 0x1B) throw new Exception("Invalid packet passed to OnLoginConfirm.");

                bool expected = (World.PlayerSerial == World.InvalidSerial);
                uint serial = ByteConverter.BigEndian.ToUInt32(data, 1);

                if (!expected && World.PlayerSerial != serial) {
                    Trace.WriteLine("Invalid serial in LoginConfirm! Packet ignored.", "World");
                    return CallbackResult.Normal;
                }

                World.PlayerSerial = serial;

                RealCharacter chr = World.FindRealCharacter(World.PlayerSerial);
                if (chr == null) {
                    chr = new RealCharacter(World.PlayerSerial);
                    World.Add(chr);
                }

                chr.Graphic = ByteConverter.BigEndian.ToUInt16(data, 9);

                chr.X = ByteConverter.BigEndian.ToUInt16(data, 11);
                chr.Y = ByteConverter.BigEndian.ToUInt16(data, 13);
                chr.Z = ByteConverter.BigEndian.ToSByte(data, 16);

                chr.Direction = ByteConverter.BigEndian.ToByte(data, 17);

                WalkHandling.ClearStack();

                if (expected)
                    Trace.WriteLine(String.Format("Player logged in. ({0}).", chr), "World");
                else
                    Trace.WriteLine("Unexpected LoginConfirm packet.", "World");

                return CallbackResult.Normal;
            }
        }
        static CallbackResult OnCharacterUpdate(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                PacketReader reader = new PacketReader(data);

                if (reader.ReadByte() != 0x77) throw new Exception("Invalid packet passed to OnCharacterUpdate.");

                bool newCharacter = false;
                uint serial = reader.ReadUInt32();

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null) {
                    chr = new RealCharacter(serial);
                    World.Add(chr);
                    newCharacter = true;
                }

                chr.Graphic = reader.ReadUInt16();
                chr.X = reader.ReadUInt16();
                chr.Y = reader.ReadUInt16();
                chr.Z = reader.ReadSByte();

                chr.Direction = reader.ReadByte();
                chr.Color = reader.ReadUInt16();
                chr.Flags = reader.ReadByte();
                chr.Notoriety = reader.ReadByte();

            #if WORLDDEBUG
                Debug.WriteLine(String.Format("Character updated ({0}).", chr.Description), "World");
            #endif

                if (newCharacter)
                    characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial));

                ObjectChanged(serial, ObjectChangeType.CharUpdated);
                return CallbackResult.Normal;
            }
        }
        static CallbackResult OnCharacterInformation(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                PacketReader reader = new PacketReader(data);

                if (reader.ReadByte() != 0x78) throw new Exception("Invalid packet passed to OnCharacterInformation.");

                ushort blockSize = reader.ReadUInt16();
                if (data.Length != blockSize)
                    Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x78 doesn't meet data lenght ({1}).", data.Length), "World");

                bool newCharacter = false;
                uint serial = reader.ReadUInt32();

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null) {
                    chr = new RealCharacter(serial);
                    World.Add(chr);
                    newCharacter = true;
                }

                chr.Graphic = reader.ReadUInt16();
                chr.X = reader.ReadUInt16();
                chr.Y = reader.ReadUInt16();
                chr.Z = reader.ReadSByte();

                chr.Direction = reader.ReadByte();
                chr.Color = reader.ReadUInt16();
                chr.Flags = reader.ReadByte();
                chr.Notoriety = reader.ReadByte();

                if (newCharacter)
                    characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial));

                ObjectChanged(serial, ObjectChangeType.CharUpdated);

                // Items
                while (reader.Offset < blockSize) {
                    uint itemSerial = reader.ReadUInt32();

                    if (itemSerial == 0)
                        return CallbackResult.Normal;

                    bool isNew = false;
                    RealItem item = World.FindRealItem(itemSerial);
                    if (item == null) {
                        item = new RealItem(itemSerial);
                        World.Add(item);
                        isNew = true;
                    }

                    item.Detach();

                    ushort graphic = reader.ReadUInt16();
                    item.Graphic = (ushort)(graphic & 0x7FFF);

                    item.Layer = reader.ReadByte();

                    if ((graphic & 0x8000) != 0) {
                        item.Color = reader.ReadUInt16();
                    }

                    item.Container = chr.Serial;
                    chr.Layers[item.Layer] = item.Serial;

            #if WORLDDEBUG
                    Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World");
            #endif
                    if (isNew)
                        itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem));

                    itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.ItemUpdated));
                    ObjectChanged(itemSerial, ObjectChangeType.ItemUpdated);
                }

            #if WORLDDEBUG
                Trace.WriteLine(String.Format("Character updated ({0}).", chr), "World");
            #endif

                return CallbackResult.Normal;
            }
        }
Beispiel #12
0
        /// <param name="limit">Maximum count of items that can be deleted.</param>
        public static void CleanUp(int limit)
        {
            if (Core.LoggedIn)
            {
                System.Diagnostics.Stopwatch watch = new Stopwatch();
                watch.Start();

                List <uint> itemRemoveList = new List <uint>();
                List <uint> charRemoveList = new List <uint>();

                lock (SyncRoot) {
                    if (playerSerial != 0 && playerSerial != uint.MaxValue)
                    {
                        foreach (KeyValuePair <uint, RealItem> pair in itemList)
                        {
                            RealItem item = pair.Value;
                            int      dist = item.GetDistance(World.RealPlayer);
                            if ((item.Container == 0 && dist > cleanUpDistance) ||
                                (item.Container != 0 && !itemList.ContainsKey(item.Container) && !charList.ContainsKey(item.Container)))
                            {
                                itemRemoveList.Add(item.Serial);
                                GetContainerContents(item.Serial, itemRemoveList);
                            }

                            if (itemRemoveList.Count > limit)
                            {
                                break;
                            }
                        }

                        foreach (KeyValuePair <uint, RealCharacter> pair in charList)
                        {
                            RealCharacter chr = pair.Value;
                            if (chr.GetDistance(World.RealPlayer) > cleanUpDistance)
                            {
                                charRemoveList.Add(chr.Serial);

                                for (int l = 0; l < chr.Layers.Length; l++)
                                {
                                    if (chr.Layers[l] != 0)
                                    {
                                        itemRemoveList.Add(chr.Layers[l]);
                                        GetContainerContents(chr.Layers[l], itemRemoveList);
                                    }
                                }

                                if (charRemoveList.Count > limit)
                                {
                                    break;
                                }
                            }
                        }

                        for (int i = 0; i < charRemoveList.Count; i++)
                        {
                            charList.Remove(charRemoveList[i]);
                        }

                        for (int i = 0; i < itemRemoveList.Count; i++)
                        {
                            itemList.Remove(itemRemoveList[i]);
                        }
                    }
                }

                watch.Stop();

                if (itemRemoveList.Count > 0 || charRemoveList.Count > 0)
                {
                    Trace.WriteLine(String.Format("World cleaned ({0} seconds). Wiped items: {1} characters: {2}", watch.ElapsedMilliseconds / 1000.0f, itemRemoveList.Count, charRemoveList.Count), "World");
                    Trace.WriteLine(String.Format("{0} items {1} characters.", itemList.Count, charList.Count), "World");
                }
            }

            worldCleaned.InvokeAsync(null, EventArgs.Empty);
        }
Beispiel #13
0
        internal static void Add(RealCharacter character)
        {
            lock (World.SyncRoot) {
                if (character == null) throw new ArgumentNullException("character");
                if (itemList.ContainsKey(character.Serial))
                    throw new InternalErrorException("Serial already exists.");

                charList.Add(character.Serial, character);
            }
        }
Beispiel #14
0
        static CallbackResult OnCharacterInformation(byte[] data, CallbackResult prevResult)
        {
            lock (World.SyncRoot) {
                PacketReader reader = new PacketReader(data);

                if (reader.ReadByte() != 0x78)
                {
                    throw new Exception("Invalid packet passed to OnCharacterInformation.");
                }

                ushort blockSize = reader.ReadUInt16();
                if (data.Length != blockSize)
                {
                    Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x78 doesn't meet data lenght ({1}).", data.Length), "World");
                }

                bool newCharacter = false;
                uint serial       = reader.ReadUInt32();

                RealCharacter chr = World.FindRealCharacter(serial);
                if (chr == null)
                {
                    chr = new RealCharacter(serial);
                    World.Add(chr);
                    newCharacter = true;
                }

                chr.Graphic = reader.ReadUInt16();
                chr.X       = reader.ReadUInt16();
                chr.Y       = reader.ReadUInt16();
                chr.Z       = reader.ReadSByte();

                chr.Direction = reader.ReadByte();
                chr.Color     = reader.ReadUInt16();
                chr.Flags     = reader.ReadByte();
                chr.Notoriety = reader.ReadByte();

                if (newCharacter)
                {
                    characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial));
                }

                ObjectChanged(serial, ObjectChangeType.CharUpdated);

                // Items
                while (reader.Offset < blockSize)
                {
                    uint itemSerial = reader.ReadUInt32();

                    if (itemSerial == 0)
                    {
                        return(CallbackResult.Normal);
                    }

                    bool     isNew = false;
                    RealItem item  = World.FindRealItem(itemSerial);
                    if (item == null)
                    {
                        item = new RealItem(itemSerial);
                        World.Add(item);
                        isNew = true;
                    }

                    item.Detach();

                    ushort graphic = reader.ReadUInt16();
                    item.Graphic = (ushort)(graphic & 0x7FFF);

                    item.Layer = reader.ReadByte();

                    if ((graphic & 0x8000) != 0)
                    {
                        item.Color = reader.ReadUInt16();
                    }

                    item.Container         = chr.Serial;
                    chr.Layers[item.Layer] = item.Serial;

#if WORLDDEBUG
                    Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World");
#endif
                    if (isNew)
                    {
                        itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem));
                    }

                    itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.ItemUpdated));
                    ObjectChanged(itemSerial, ObjectChangeType.ItemUpdated);
                }

#if WORLDDEBUG
                Trace.WriteLine(String.Format("Character updated ({0}).", chr), "World");
#endif

                return(CallbackResult.Normal);
            }
        }