public void Decode(MaplePacket pPacket)
        {
            pPacket.ReadByte(); // ?


            Running = new Dictionary<ushort, string>();
            Done = new Dictionary<ushort, long>();

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                Running.Add(pPacket.ReadUShort(), pPacket.ReadString());
            }

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.ReadString();
                pPacket.ReadString();
            }

            pPacket.ReadByte(); // ?

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                Done.Add(pPacket.ReadUShort(), pPacket.ReadLong());
            }
        }
        public virtual void HandleLogin(ClientConnection pConnection, MaplePacket pPacket)
        {
            int error = pPacket.ReadInt();
            pPacket.ReadShort();
            if (error != 0)
            {
                pConnection.Logger_WriteLine("Got Status: {0}", error);
                if (error == 0x07)
                {
                    pConnection.Logger_WriteLine("Already logged in!");
                }
                return;
            }

            int userid = pPacket.ReadInt();
            byte gender = pPacket.ReadByte(); // Gender or GenderSelect/PinSelect
            pPacket.ReadByte();
            short admin = pPacket.ReadShort();
            pPacket.ReadInt(); // ReadBytes(4)
            pPacket.ReadByte(); // 0x95
            string username = pPacket.ReadString(); // Username

            pPacket.ReadByte(); // 0?


            byte qban = pPacket.ReadByte(); // Quiet Ban
            DateTime qban_time = DateTime.FromFileTime(pPacket.ReadLong()); // Quiet Ban Time
            DateTime creationtime = DateTime.FromFileTime(pPacket.ReadLong()); // Creation Time
            pPacket.ReadInt(); // 78?
            pPacket.Skip(2); // 1 1
            pPacket.ReadBytes(8); // CC key

            ParseLogin(pConnection, userid, username, creationtime);
        }
        public void Decode(ClientConnection pConnection, MaplePacket pPacket)
        {
            var v = pPacket.ReadByte(); // ?


            Running = new Dictionary<ushort, string>();
            Done = new Dictionary<ushort, long>();

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                Running.Add(pPacket.ReadUShort(), pPacket.ReadString());
            }

            if (v == 0)
            {
                for (int i = pPacket.ReadShort(); i > 0; i--)
                {
                    pPacket.ReadShort(); // UNK lol
                }
            }

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.ReadString(); // 1NX1702337
                pPacket.ReadString(); // '1' or '0 ' ?!
            }

            var hurr = pPacket.ReadByte(); // ?

            // ADDED IN v.128 !!!!
            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                // New method of creating dates...
                var id = pPacket.ReadUShort();
                var date = pPacket.ReadUInt();

                long ft = DecodeTimeFromInt(pConnection, date);

                if (!Done.ContainsKey(id))
                    Done.Add(id, ft);
                else
                    pConnection.Logger_WriteLine("Duplicate Quest (Done): {0}", id);

            }

            if (hurr == 0)
            {
                for (int i = pPacket.ReadShort(); i > 0; i--)
                {
                    Done.Add(pPacket.ReadUShort(), pPacket.ReadLong());
                }
            }
        }
        public static ItemBase DecodeItemData(ClientConnection pConnection, MaplePacket pPacket)
        {
            byte type = pPacket.ReadByte();
            ItemBase ret = null;
            switch (type)
            {
                case 1:
                    ret = new ItemEquip();
                    ret.Amount = 1;
                    break;
                case 2: ret = new ItemRechargable(); break;
                case 3:
                    ret = new ItemPet();
                    ret.Amount = 1;
                    break;
                default:
                    {
                        Logger.WriteLine("Unkown ItemType: {0}", type);
                        return null;
                    }
            }

            ret.Decode(pConnection, pPacket);

            return ret;
        }
        public virtual void HandleVersion(ClientConnection pConnection, MaplePacket pPacket)
        {
            byte locale = pPacket.ReadByte();
            ushort version = pPacket.ReadUShort();
            ushort subversion = pPacket.ReadUShort();

            pConnection.Logger_WriteLine("Detected MapleStory version of client: {1}.{2} (locale: {0})", locale, version, subversion);
            pConnection.MapleVersion = version;

            pConnection.CharData = null; // Back to the LoginServer!!!
            if (locale != ServerMapleInfo.LOCALE)
            {
                pConnection.Logger_WriteLine("Incompatible MapleStory locale detected!!!!");
                pConnection.SendInfoText("Unsupported MapleStory client detected. Mapler.me only supports MapleStory Global version {0} at the moment.", ServerMapleInfo.VERSION); // This should _never_ happen XD (different encryption and such)
                pConnection.Disconnect();
            }
            else if (version > ServerMapleInfo.VERSION)
            {
                pConnection.Logger_WriteLine("MapleStory client of user is outdated/incorrect. Disconnect.");
                pConnection.SendInfoText("Your MapleStory client seems outdated. Update your client in order to use the Mapler.me service.\r\nVersion identified: {0}\r\nSupported version: {1}", version, ServerMapleInfo.VERSION);
                pConnection.Disconnect();
            }
            else if (version < ServerMapleInfo.VERSION)
            {
                pConnection.Logger_WriteLine("MapleStory client of user is more up-to-date than Mapler.me service!!!");
                pConnection.SendInfoText("As your client is more up-to-date than the Mapler.me service, you are unable to use the Mapler.me service at this time.\r\nCheck the Mapler.me website and/or Twitter (@maplerme) for updates!\r\n\r\nCurrently supported version: {0}\r\nYour version: {1}", ServerMapleInfo.VERSION, version);
                pConnection.Disconnect();
            }

        }
        public void Decode(MaplePacket pPacket)
        {
            InventorySlots = new byte[INVENTORIES];
            for (int i = 0; i < INVENTORIES; i++)
                InventorySlots[i] = pPacket.ReadByte();

            pPacket.ReadLong(); // 94354848000000000 | 1-1-1900



            EquipmentItems = new Dictionary<short, ItemEquip>[EQUIP_INVENTORIES];

            for (byte i = 0; i < EQUIP_INVENTORIES; i++)
            {
                EquipmentItems[i] = new Dictionary<short, ItemEquip>();

                while (true)
                {
                    short slot = pPacket.ReadShort();
                    if (slot == 0) break;

                    ItemEquip equip = (ItemEquip)ItemBase.DecodeItemData(pPacket);

                    EquipmentItems[i].Add(slot, equip);
                }
            }

            InventoryItems = new Dictionary<byte, ItemBase>[NORMAL_INVENTORIES];

            for (byte i = 0; i < NORMAL_INVENTORIES; i++)
            {
                InventoryItems[i] = new Dictionary<byte, ItemBase>();

                while (true)
                {
                    byte slot = pPacket.ReadByte();
                    if (slot == 0) break;

                    ItemBase item = ItemBase.DecodeItemData(pPacket);

                    InventoryItems[i].Add(slot, item);
                }
            }
        }
Exemple #7
0
        public void Decode(MaplePacket pPacket)
        {
            this.ID = pPacket.ReadInt();
            this.Type = pPacket.ReadByte();

            pPacket.ReadShort(); // X
            pPacket.ReadShort(); // Y
            pPacket.ReadByte(); // Stance
            pPacket.ReadShort(); // Foothold

            this.Skin = (byte)pPacket.ReadShort();
            this.Hair = pPacket.ReadShort();
            this.Face = pPacket.ReadShort();
            this.Name = pPacket.ReadString();

            this.Equips = new int[7];
            for (int i = 0; i < 7; i++)
                this.Equips[i] = pPacket.ReadInt();
        }
Exemple #8
0
            public DumpPacket(MaplePacket pPacket)
            {
                pPacket.Reset();
                MaplePacket.CommunicationType type = (MaplePacket.CommunicationType)pPacket.ReadByte();
                Outboud = type == MaplePacket.CommunicationType.ClientPacket;
                Opcode = pPacket.ReadUShort();

                Data = new byte[pPacket.Length - 3];
                Buffer.BlockCopy(pPacket.ToArray(), 3, Data, 0, Data.Length); // byte + short (header)
                ArrivalTime = MasterThread.CurrentDate;
                pPacket.Reset();
            }
        public override void HandleLogin(ClientConnection pConnection, MaplePacket pPacket)
        {
            byte error = pPacket.ReadByte();
            if (error != 0)
            {
                pConnection.Logger_WriteLine("Got Status: {0}", error);
                if (error == 0x07)
                {
                    pConnection.Logger_WriteLine("Already logged in?");
                }
                return;
            }

            int userid = pPacket.ReadInt();
            pPacket.ReadByte(); // Gender or GenderSelect/PinSelect
            pPacket.ReadByte();
            pPacket.ReadByte(); // Admin? Has bitflag 5
            string username = pPacket.ReadString(); // Username
            pPacket.ReadByte();
            pPacket.ReadByte();
            DateTime creationtime = DateTime.FromFileTime(pPacket.ReadLong()); // Incorrect :/. Nowhere to be found

            if (pPacket.ReadBool() == false)
                pPacket.ReadString(); // Username, with astriks as protection: 'd**mondo2*'

            pPacket.ReadString(); // wat.
            if (pPacket.ReadBool())
                pPacket.ReadBytes(15); // Every job that can be chosen

            pPacket.ReadInt(); // YYYYMMDDHH, as in character info -.-?


            ParseLogin(pConnection, userid, username, creationtime);
        }
        public virtual void HandleLoginFromWeb(ClientConnection pConnection, MaplePacket pPacket)
        {
            byte error = pPacket.ReadByte();
            if (error != 0)
            {
                pConnection.Logger_WriteLine("Got Status: {0}", error);
                if (error == 0x07)
                {
                    pConnection.Logger_WriteLine("Already logged in!");
                }
                return;
            }

            int userid = pPacket.ReadInt();
            pPacket.ReadByte(); // Gender or GenderSelect/PinSelect
            pPacket.ReadByte();
            pPacket.ReadShort(); // Admin info!
            pPacket.ReadInt(); // ReadBytes(4)
            pPacket.ReadByte(); // 0x95
            string username = pPacket.ReadString(); // Username

            pPacket.ReadByte(); // 0?


            pPacket.ReadByte(); // Quiet Ban
            pPacket.ReadLong(); // Quiet Ban Time
            pPacket.ReadString(); // Username. Again.
            DateTime creationtime = DateTime.FromFileTime(pPacket.ReadLong()); // creation datetime
            pPacket.ReadInt();
            pPacket.ReadBytes(8); // CC key
            pPacket.ReadString();

            ParseLogin(pConnection, userid, username, creationtime);
        }
Exemple #11
0
        public void Decode(MaplePacket pPacket)
        {
            this.ID = pPacket.ReadInt();
            this.Name = pPacket.ReadString();
            this.Ranks = new string[5];
            for (int i = 0; i < 5; i++)
                this.Ranks[i] = pPacket.ReadString();

            byte guilds = pPacket.ReadByte();
            this.GuildIDs = new int[guilds];
            for (int i = 0; i < guilds; i++)
                this.GuildIDs[i] = pPacket.ReadInt();

            this.Capacity = pPacket.ReadInt();
            this.Notice = pPacket.ReadString();
        }
Exemple #12
0
        public void Decode(MaplePacket pPacket)
        {
            this.Gender = pPacket.ReadByte(); // Gender
            this.Skin = pPacket.ReadByte(); // Skin
            this.Face = pPacket.ReadInt(); // Face

            this.JobID = pPacket.ReadInt(); // Job ID

            pPacket.ReadByte(); // First slot; hair
               this.Hair = pPacket.ReadInt(); // Hair ID

            Equips = new Dictionary<byte, int>[3];
            Equips[0] = new Dictionary<byte, int>();
            Equips[1] = new Dictionary<byte, int>();
            Equips[2] = new Dictionary<byte, int>();

            while (true)
            {
                byte slot = pPacket.ReadByte();
                if (slot == 0xFF) break;
                Equips[0].Add(slot, pPacket.ReadInt());
            }
            while (true)
            {
                byte slot = pPacket.ReadByte();
                if (slot == 0xFF) break;
                Equips[1].Add(slot, pPacket.ReadInt());
            }
            while (true)
            {
                byte slot = pPacket.ReadByte();
                if (slot == 0xFF) break;
                Equips[2].Add(slot, pPacket.ReadInt());
            }

            pPacket.ReadInt();
            pPacket.ReadInt();
            pPacket.ReadInt();

            pPacket.ReadByte();
            pPacket.ReadInt();
            pPacket.ReadInt();
            pPacket.ReadInt();

            if (this.JobID / 100 == 31 || this.JobID / 100 == 36 || this.JobID == 3001 || this.JobID == 3002)
            {
                this.Wings = pPacket.ReadInt();
            }
        }
        public void Decode(MaplePacket pPacket)
        {
            ChosenCardID = pPacket.ReadInt();

            if (pPacket.ReadBool() == false)
            {
                for (short cards = pPacket.ReadShort(); cards > 0; cards--)
                {
                    pPacket.ReadShort(); // CardID
                    pPacket.ReadByte(); // Level
                }
            }
            else
            {
                // Unknown stuff...
                pPacket.ReadShort();
                short size = pPacket.ReadShort();
                pPacket.Skip(size); // Card block

                size = pPacket.ReadShort();
                pPacket.Skip(size); // Levels
            }
        }
        public virtual void HandleKeymapUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            int mode = pPacket.ReadInt();
            if (mode == 0)
            {
                Dictionary<byte, KeyValuePair<byte, int>> modifieds = new Dictionary<byte, KeyValuePair<byte, int>>();
                int amount = pPacket.ReadInt();
                for (int i = 0; i < amount; i++)
                {
                    int idx = pPacket.ReadInt();
                    byte type = pPacket.ReadByte();
                    int value = pPacket.ReadInt();

                    if (idx < 0 || idx > ServerMapleInfo.KEYMAP_SLOTS)
                    {
                        pConnection.Logger_WriteLine("ERROR: Keymap contained invalid index!");
                        return;
                    }

                    if (modifieds.ContainsKey((byte)idx)) continue; // -.-''

                    modifieds.Add((byte)idx, new KeyValuePair<byte, int>(type, value));
                }

                if (modifieds.Count == 0) return;

                StringBuilder sb = new StringBuilder();
                sb.Append("UPDATE character_keymaps SET ");
                foreach (var kvp in modifieds)
                    sb.AppendFormat("map_{0}_type = {1}, map_{0}_value = {2},", kvp.Key, kvp.Value.Key, kvp.Value.Value);

                sb.Append(" WHERE character_id = " + pConnection.CharacterInternalID);

                MySQL_Connection.Instance.RunQuery(sb.ToString().Replace(", WHERE", " WHERE"));

            }
        }
        public override void Decode(MaplePacket pPacket)
        {
            base.Decode(pPacket);


            this.Slots = pPacket.ReadByte();
            this.Scrolls = pPacket.ReadByte();
            this.Str = pPacket.ReadShort();
            this.Dex = pPacket.ReadShort();
            this.Int = pPacket.ReadShort();
            this.Luk = pPacket.ReadShort();
            this.HP = pPacket.ReadShort();
            this.MP = pPacket.ReadShort();
            this.Watk = pPacket.ReadShort();
            this.Matk = pPacket.ReadShort();
            this.Wdef = pPacket.ReadShort();
            this.Mdef = pPacket.ReadShort();
            this.Acc = pPacket.ReadShort();
            this.Avo = pPacket.ReadShort();
            this.Hands = pPacket.ReadShort();
            this.Speed = pPacket.ReadShort();
            this.Jump = pPacket.ReadShort();

            this.Name = pPacket.ReadString();
            this.Flags = pPacket.ReadShort();

            pPacket.ReadByte(); // Increases Skill
            this.Level = pPacket.ReadByte();

            pPacket.ReadInt();
            pPacket.ReadInt(); // 
            this.ViciousHammer = pPacket.ReadInt();

            pPacket.ReadShort(); // PVP damage

            pPacket.ReadByte();
            pPacket.ReadByte();

            this.Potential1 = pPacket.ReadShort();
            this.Potential2 = pPacket.ReadShort();
            this.Potential3 = pPacket.ReadShort();
            this.Potential4 = pPacket.ReadShort();
            this.Potential5 = pPacket.ReadShort();

            pPacket.ReadShort(); // New?

            this.SocketState = pPacket.ReadShort();
            this.Socket1 = pPacket.ReadShort();
            this.Socket2 = pPacket.ReadShort();
            this.Socket3 = pPacket.ReadShort();

            pPacket.ReadLong();

            pPacket.ReadLong();

            pPacket.ReadInt();
        }
 private static byte FlaggedValue(ClientConnection pConnection, int pItemID, uint pValue, uint pFlag, MaplePacket pPacket, byte pTypeValue, bool pLogIfFound = false)
 {
     if (pValue.HasFlag(pFlag))
     {
         var val = pPacket.ReadByte();
         if (pLogIfFound)
             pConnection.Logger_WriteLine("Found flag {3} {0:X8}: {1} | ItemID: {2}", pFlag, val, pItemID, pTypeValue.GetType().Name);
         return val;
     }
     else
         return 0;
 }
        public override void Decode(ClientConnection pConnection, MaplePacket pPacket)
        {
            base.Decode(pConnection, pPacket);

            Petname = pPacket.ReadString(13);
            Level = pPacket.ReadByte();
            Closeness = pPacket.ReadShort();
            Fullness = pPacket.ReadByte();

            this.Expires = pPacket.ReadLong();
            pPacket.Skip(2 + 2 + 4 + 2 + 1 + 4 + 4 + 2);
            // Last 2:
            // - int: -1
            // - short: 100
            // V.132: + 2
        }
        public override void OnPacket(MaplePacket pPacket)
        {
            MasterThread.Instance.AddCallback((a) =>
            {
                try
                {
                    if (Disconnected) return; // Just to be sure...

                    if (_exporter != null)
                        _exporter.AddPacket(pPacket);

                    MaplePacket.CommunicationType type = (MaplePacket.CommunicationType)pPacket.ReadByte();
                    ushort opcode = pPacket.ReadUShort();

                    if (IsFake)
                    {
                        Logger.WriteLine("Emulating {0:X4} (Len: {1})", opcode, pPacket.Length);
                    }

                    if ((byte)type < Program.ValidHeaders.Length)
                    {
                        // Check if packet is accepted
                        var list = Program.ValidHeaders[(byte)type];
                        if (list.ContainsKey(opcode))
                        {
                            var action = list[opcode];
                            if (action != null)
                            {
                                try
                                {
                                    if (action.CanHandle == null || action.CanHandle(this))
                                        action.Handle(this, pPacket);
                                }
                                catch (Exception ex)
                                {
                                    Logger_ErrorLog("Failed parsing {0:X4} for {1}", opcode, type);
                                    Logger_WriteLine(ex.ToString());
                                    if (!IsFake)
                                    {
                                        LogFilename += "ERROR";
                                        SendInfoText("An error occurred on the Mapler.me server! Please report this :)");

                                        // Save exception to packet
                                        using (MaplePacket mp = new MaplePacket(MaplePacket.CommunicationType.ServerPacket, 0x9999))
                                        {
                                            mp.WriteString(ex.ToString());
                                            if (ex.ToString().Contains("MySql.Data.MySqlClient.MySqlException"))
                                            {
                                                Logger_ErrorLog("MySQL exception!");
                                                var queries = MySQL_Connection.Instance.GetRanQueries();
                                                mp.WriteInt(queries.Count);
                                                foreach (var kvp in queries)
                                                {
                                                    mp.WriteString(kvp.Key);
                                                    mp.WriteString(kvp.Value);
                                                }

                                            }
                                            mp.SwitchOver(); // Make read packet
                                            _exporter.AddPacket(mp);
                                        }

                                        Save(false, false);
                                    }
                                }
                            }
                            else
                            {
                                if (!IsFake)
                                    Logger_WriteLine("No action for {0:X4}", opcode);
                            }
                        }
                        else
                        {
                            if (!IsFake)
                                Logger_WriteLine("Client sent packet {0:X4} for {1} but this one is not handled!", opcode, type);
                        }
                    }
                    else
                    {
                        Logger_ErrorLog("Packet Type not accepted!!! {0:X4} {1}", opcode, (byte)type);
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorLog("Failed handling packet: {0}", ex.ToString());
                    SendInfoText("An error occurred on the Mapler.me server! Please report this :)");
                }
                pPacket.Dispose();
                pPacket = null;
            });
        }
        public virtual void HandleFamiliarList(ClientConnection pConnection, MaplePacket pPacket)
        {
            using (InsertQueryBuilder familiars = new InsertQueryBuilder("familiars"))
            {
                familiars.OnDuplicateUpdate = true;

                familiars.AddColumn("character_id");
                familiars.AddColumn("mobid");
                familiars.AddColumns(true,
                    "name", "fitality_cur", "fitality_max",
                    "starttime", "endtime", "unktime"
                );

                for (int i = pPacket.ReadInt(); i > 0; i--)
                {
                    pPacket.ReadInt(); // Weird id?
                    int mobid = pPacket.ReadInt();
                    string name = pPacket.ReadString(13);
                    byte currentfit = pPacket.ReadByte();
                    byte maxfit = pPacket.ReadByte();
                    pPacket.ReadInt();
                    pPacket.ReadByte();
                    DateTime starttime = DateTime.FromFileTime(pPacket.ReadLong());
                    DateTime unktime = DateTime.FromFileTime(pPacket.ReadLong());
                    DateTime endtime = DateTime.FromFileTime(pPacket.ReadLong());

                    pPacket.ReadByte();
                    pPacket.ReadByte();


                    familiars.AddRow(
                        pConnection.CharacterInternalID,
                        mobid,
                        name,
                        currentfit,
                        maxfit,
                        starttime,
                        endtime,
                        unktime
                        );

                }

                familiars.RunQuery();
            }
        }
        public virtual void HandleSkillUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            pPacket.ReadByte(); // Unstuck
            pPacket.ReadByte();
            ushort amount = pPacket.ReadUShort();

            using (InsertQueryBuilder skillTable = new InsertQueryBuilder("skills"))
            {
                skillTable.OnDuplicateUpdate = true;
                skillTable.AddColumn("character_id", false);
                skillTable.AddColumn("skillid", false);
                skillTable.AddColumn("level", true);
                skillTable.AddColumn("maxlevel", true);
                skillTable.AddColumn("expires", true);

                for (ushort i = 0; i < amount; i++)
                {
                    int skillid = pPacket.ReadInt();
                    int level = pPacket.ReadInt();
                    int masterlevel = pPacket.ReadInt();
                    long expiration = pPacket.ReadLong();

                    Timeline.Instance.PushSkillUP(pConnection, skillid, level);

                    skillTable.AddRow(pConnection.CharacterInternalID, skillid, level, masterlevel == 0 ? null : (object)masterlevel, expiration);
                }

                if (skillTable.RowCount > 0)
                {
                    string q = skillTable.ToString();
                    System.IO.File.WriteAllText("insert-update-skills-packet.sql", q);
                    int result = (int)MySQL_Connection.Instance.RunQuery(q);
                    pConnection.Logger_WriteLine("Result Skills: {0}", result);

                    pConnection.SendTimeUpdate();
                }

            }
        }
        public virtual void HandleBuddyList(ClientConnection pConnection, MaplePacket pPacket)
        {
            byte mode = pPacket.ReadByte();
            if (mode != 0x07) return;

            MySQL_Connection.Instance.RunQuery(string.Format("DELETE FROM buddies WHERE character_id = {0}", pConnection.CharacterInternalID));
            using (InsertQueryBuilder buddies = new InsertQueryBuilder("buddies"))
            {
                buddies.OnDuplicateUpdate = true;
                buddies.AddColumn("character_id");
                buddies.AddColumn("friend_id");
                buddies.AddColumns(true, "friend_name", "group_name");

                byte amount = pPacket.ReadByte();
                for (byte i = 0; i < amount; i++)
                {
                    int bid = pPacket.ReadInt();
                    string bname = pPacket.ReadString(13);
                    pPacket.Skip(1 + 4);
                    string gname = pPacket.ReadString(13);
                    pPacket.Skip(4);

                    buddies.AddRow(
                        pConnection.CharacterInternalID,
                        bid,
                        bname,
                        gname
                        );
                }
                buddies.RunQuery();
            }
        }
        public override void Decode(MaplePacket pPacket)
        {
            base.Decode(pPacket);

            Petname = pPacket.ReadString(13);
            Level = pPacket.ReadByte();
            Closeness = pPacket.ReadShort();
            Fullness = pPacket.ReadByte();


            pPacket.Skip(8 + 2 + 2 + 4 + 2 + 1 + 4 + 4);
        }
        public override void OnPacket(MaplePacket pPacket)
        {
            byte type = pPacket.ReadByte();
            ushort header = pPacket.ReadUShort();
            if (header >= 0xEE00)
            {
                if (header == 0xEEFF)
                {
                    string version = pPacket.ReadString();
                    if (version != Logger.Version)
                    {

                        if (frmMain.Instance != null)
                        {
                            frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate
                            {
                                System.Windows.Forms.MessageBox.Show(frmMain.Instance, "You are using an outdated version of Mapler.me! Check the site for the latest updates.", "Mapler.me server connection error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                            });
                        }
                        else
                        {
                            System.Windows.Forms.MessageBox.Show("You are using an outdated version of Mapler.me! Check the site for the latest updates.", "Mapler.me server connection error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                        }
                        Environment.Exit(3);
                        return;
                    }


                    // Crypto
                    byte[] sendkey = pPacket.ReadBytes(32),
                        recvkey = pPacket.ReadBytes(32);

                    SetKeys(sendkey, recvkey);

                    _validHeaders = new List<ushort>[(byte)MaplePacket.CommunicationType.AMOUNT];
                    for (byte i = 0; i < (byte)MaplePacket.CommunicationType.AMOUNT; i++)
                    {
                        _validHeaders[i] = new List<ushort>();
                        for (ushort j = pPacket.ReadUShort(); j > 0; j--)
                        {
                            ushort tmp = pPacket.ReadUShort();
                            // Logger.WriteLine("{0} accepts 0x{1:X4}", (MaplePacket.CommunicationType)i, tmp);
                            _validHeaders[i].Add(tmp);
                        }
                    }


                    for (byte j = pPacket.ReadByte(); j > 0; j--)
                    {
                        string ip = pPacket.ReadString();
                        AcceptedIPs.Add(ip);
                    }

                    if (pPacket.ReadBool())
                        MapleStoryCryptoKey = pPacket.ReadBytes(32);

                    AcceptedMapleStoryLocale = pPacket.ReadByte();
                    AcceptedMapleStoryVersion = pPacket.ReadUShort();
                    Logger.WriteLine("Initialized keys and valid headers");

                    SendToken(Program.Token);
                }
                else if (header == 0xEEFE)
                {
                    // Create screenshot and send to server

                    string url = pPacket.ReadString();
                    string data = pPacket.ReadString();

                    string filename = System.IO.Path.GetTempFileName();

                    bool done = Screenshot.MakeScreenshotOfMaple(filename);
                    if (done)
                    {
                        Screenshot.Upload(url, data, filename);
                    }
                }
                else if (header == 0xEEFD)
                {
                    string charname = pPacket.ReadString();
                    frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate
                    {
                        frmMain.Instance.lblLastUpdate.Text = string.Format("{0} (Character: {1})", DateTime.Now, charname);
                    });
                }
                else if (header == 0xEEFC)
                {
                    frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate
                    {
                        frmMain.Instance.lblInfo.Text = pPacket.ReadString();
                    });
                }
                else if (header == 0xEE01)
                {
                    // Pingpong
                    using (MaplePacket mp = new MaplePacket(MaplePacket.CommunicationType.ClientPacket, 0xEE01))
                    {
                        SendPacket(mp);
                    }
                }
            }

            pPacket.Dispose();
            pPacket = null;
        }
        public virtual void HandleAbilityInfoUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            pPacket.ReadByte(); // Unlock
            if (pPacket.ReadBool() == false) return;

            var stat = new Tuple<byte, int, byte>((byte)pPacket.ReadShort(), pPacket.ReadInt(), (byte)pPacket.ReadShort());
            pPacket.ReadShort();

            using (InsertQueryBuilder table = new InsertQueryBuilder("character_abilities"))
            {
                table.OnDuplicateUpdate = true;

                table.AddColumn("character_id");
                table.AddColumn("id");
                table.AddColumn("skill_id", true);
                table.AddColumn("level", true);


                table.AddRow(
                    pConnection.CharacterInternalID,
                    stat.Item1,
                    stat.Item2,
                    stat.Item3
                    );

                table.RunQuery();
            }
        }
        public void Decode(ClientConnection pConnection, MaplePacket pPacket)
        {
            InventorySlots = new byte[INVENTORIES];
            for (int i = 0; i < INVENTORIES; i++)
                InventorySlots[i] = pPacket.ReadByte();

            pPacket.ReadLong(); // 94354848000000000 | 1-1-1900



            EquipmentItems = new Dictionary<short, ItemEquip>[EQUIP_INVENTORIES];
#if LOCALE_EMS
            for (byte i = 0; i < 3; i++)
            {
                EquipmentItems[i] = new Dictionary<short, ItemEquip>();

                while (true)
                {
                    short slot = pPacket.ReadShort();
                    if (slot == 0) break;
                    slot = CharacterInventory.CorrectEquipSlot(i, slot);

                    ItemEquip equip = (ItemEquip)ItemBase.DecodeItemData(pConnection, pPacket);

                    EquipmentItems[i].Add(slot, equip);
                }
            }

            pPacket.ReadBool(); // EMS only -.-

            for (byte i = 3; i < EQUIP_INVENTORIES; i++)
            {
                EquipmentItems[i] = new Dictionary<short, ItemEquip>();

                while (true)
                {
                    short slot = pPacket.ReadShort();
                    if (slot == 0) break;
                    slot = CharacterInventory.CorrectEquipSlot(i, slot);

                    ItemEquip equip = (ItemEquip)ItemBase.DecodeItemData(pConnection, pPacket);

                    EquipmentItems[i].Add(slot, equip);
                }
            }
#else
            for (byte i = 0; i < EQUIP_INVENTORIES; i++)
            {
                EquipmentItems[i] = new Dictionary<short, ItemEquip>();

                while (true)
                {
                    short slot = pPacket.ReadShort();
                    if (slot == 0) break;
                    slot = CharacterInventory.CorrectEquipSlot(i, slot);

                    ItemEquip equip = (ItemEquip)ItemBase.DecodeItemData(pConnection, pPacket);

                    EquipmentItems[i].Add(slot, equip);
                }
            }
#endif

            InventoryItems = new Dictionary<byte, ItemBase>[NORMAL_INVENTORIES];
            BagItems = new Dictionary<int, BagItem>();

            for (byte i = 0; i < NORMAL_INVENTORIES; i++)
            {
                InventoryItems[i] = new Dictionary<byte, ItemBase>();

                while (true)
                {
                    byte slot = pPacket.ReadByte();
                    if (slot == 0) break;

                    ItemBase item = ItemBase.DecodeItemData(pConnection, pPacket);
                    InventoryItems[i].Add(slot, item);

                    if (item.BagID != -1)
                    {
                        // Update BagID... O.o
                        item.BagID = GameHelper.GetBagID(item.BagID, i);

                        BagItem bi = new BagItem(item);
                        BagItems.Add(item.BagID, bi);
                    }
                }
            }

            // Bagzzz
            for (int inv = 3; inv <= 4; inv++)
            {
                var bags = pPacket.ReadInt();
                for (int i = 0; i < bags; i++)
                {
                    int bagid = pPacket.ReadInt();

                    int bagitemid = pPacket.ReadInt();

                    BagItem bi = BagItems[GameHelper.GetBagID(bagid, inv - 2)]; // No addition to inv...!

                    while (true)
                    {
                        int slotid = pPacket.ReadInt();
                        if (slotid == -1) break;

                        ItemBase item = ItemBase.DecodeItemData(pConnection, pPacket);
                        bi.Items.Add((byte)slotid, item);
                    }
                }
            }
        }
        public virtual void HandleInventorySlotsUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            CharacterInventory inventory = pConnection.CharData.Inventory;
            byte inv = pPacket.ReadByte();
            byte newslots = pPacket.ReadByte();
            if (inv < 1 || inv > 5) return;
            if (newslots < 24 || newslots > 96) return; // Just to be sure
            inventory.InventorySlots[inv - 1] = newslots;

            string slotname = "";

            switch (inv)
            {
                case 1: slotname = "eqp"; break;
                case 2: slotname = "use"; break;
                case 3: slotname = "setup"; break;
                case 4: slotname = "etc"; break;
                case 5: slotname = "cash"; break;
            }

            MySQL_Connection.Instance.RunQuery(string.Format("UPDATE characters SET {0}_slots = {1} WHERE internal_id = {2}", slotname, newslots, pConnection.CharacterInternalID));

            pConnection.SendTimeUpdate();
        }
        public virtual void HandleStatUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            pPacket.ReadByte();
            long updateFlag = pPacket.ReadLong();
            if (updateFlag == 0) return; // Fake Update -.- / Unstuck

            bool didsomething = false;

            if (CheckFlag(updateFlag, 1)) // Skin
            {
                didsomething = true;
                pConnection.CharData.Stats.Skin = pPacket.ReadByte();
            }
            if (CheckFlag(updateFlag, 2)) // Eyes
            {
                didsomething = true;
                pConnection.CharData.Stats.Face = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 4)) // Eyes
            {
                didsomething = true;
                pConnection.CharData.Stats.Hair = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 8))
            {
                didsomething = true;
                pConnection.CharData.Stats.Pets[0] = pPacket.ReadLong();
            }
            if (CheckFlag(updateFlag, 0x80000))
            {
                var value = pPacket.ReadLong();
                pConnection.Logger_WriteLine("0x80000 | {0}", value);
            }
            if (CheckFlag(updateFlag, 0x100000))
            {
                var value = pPacket.ReadLong();
                pConnection.Logger_WriteLine("0x100000 | {0}", value);
            }
            if (CheckFlag(updateFlag, 0x10))
            {
                didsomething = true;
                var level = pPacket.ReadByte();
                Timeline.Instance.PushLevelUP(pConnection, level);
                pConnection.CharData.Stats.Level = level;
                pConnection.Logger_WriteLine("{0} leveled up to level {1}!!!", pConnection.CharData.Stats.Name, level);
            }
            if (CheckFlag(updateFlag, 0x20))
            {
                didsomething = true;
                var jobid = pPacket.ReadShort();
                Timeline.Instance.PushJobUP(pConnection, (ushort)jobid);
                pConnection.CharData.Stats.JobID = jobid;
                pConnection.Logger_WriteLine("{0} changed to job {1}!!!", pConnection.CharData.Stats.Name, jobid);
            }
            if (CheckFlag(updateFlag, 0x40))
            {
                didsomething = true;
                pConnection.CharData.Stats.Str = pPacket.ReadShort();
            }
            if (CheckFlag(updateFlag, 0x80))
            {
                didsomething = true;
                pConnection.CharData.Stats.Dex = pPacket.ReadShort();
            }
            if (CheckFlag(updateFlag, 0x100))
            {
                didsomething = true;
                pConnection.CharData.Stats.Int = pPacket.ReadShort();
            }
            if (CheckFlag(updateFlag, 0x200))
            {
                didsomething = true;
                pConnection.CharData.Stats.Luk = pPacket.ReadShort();
            }
            if (CheckFlag(updateFlag, 0x400))
            {
                didsomething = true;
                pConnection.CharData.Stats.HP = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 0x800))
            {
                didsomething = true;
                pConnection.CharData.Stats.MaxHP = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 0x1000))
            {
                didsomething = true;
                pConnection.CharData.Stats.MP = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 0x2000))
            {
                didsomething = true;
                pConnection.CharData.Stats.MaxMP = pPacket.ReadInt();
            }
            if (CheckFlag(updateFlag, 0x4000))
            {
                didsomething = true;
                pConnection.CharData.Stats.AP = pPacket.ReadShort();
            }
            if (CheckFlag(updateFlag, 0x8000))
            {
                didsomething = true;

                short a1 = pConnection.CharData.Stats.JobID;
                pConnection.CharData.Stats.SPData.Clear();

                if (GameHelper.IsExtendedSPJob(pConnection.CharData.Stats.JobID))
                {

                    byte amnt = pPacket.ReadByte();
                    List<byte> haslist = new List<byte>();
                    for (int j = 0; j < amnt; j++)
                    {
                        byte v1 = pPacket.ReadByte(); // Job ID
                        int v2 = pPacket.ReadInt(); // Amount
                        pConnection.CharData.Stats.SPData.Add(new KeyValuePair<byte, int>(v1, v2));

                        haslist.Add(v1);
                    }
                    for (byte j = 1; j < 20; j++)
                    {
                        if (!haslist.Contains(j))
                            pConnection.CharData.Stats.SPData.Add(new KeyValuePair<byte, int>(j, 0));
                    }

                }
                else
                {
                    pConnection.CharData.Stats.SPData.Add(new KeyValuePair<byte, int>(0, pPacket.ReadShort()));
                }
            }

            if (CheckFlag(updateFlag, 0x10000))
            {
                didsomething = true;
                long newexp = pPacket.ReadLong();
                byte point = (byte)EXPTable.GetLevelPercentage(pConnection.CharData.Stats.Level, newexp);

                if (pConnection.LastExpPoint != point)
                {
                    // Ohhh
                    Timeline.Instance.PushExpPoint(pConnection, point);
                }

                pConnection.CharData.Stats.EXP = newexp;
                pConnection.LastExpPoint = point;

            }

            if (CheckFlag(updateFlag, 0x20000))
            {
                didsomething = true;
                int fame = pPacket.ReadInt();
                Timeline.Instance.PushGotFame(pConnection, fame - pConnection.CharData.Stats.Fame, fame);
                pConnection.CharData.Stats.Fame = fame;
            }

            if (CheckFlag(updateFlag, 0x40000))
            {
                didsomething = true;
                pConnection.CharData.Stats.Mesos = pPacket.ReadLong();
            }
            if (CheckFlag(updateFlag, 0x200000))
            {
                var value = pPacket.ReadInt();
                pConnection.Logger_WriteLine("0x200000 | {0}", value);
            }

            if (CheckFlag(updateFlag, 0x400000))
            {
                var value = pPacket.ReadByte();
                pConnection.Logger_WriteLine("0x400000 | {0}", value);
            }

            if (CheckFlag(updateFlag, 0x800000))
            {
                // Ambition/Charisma D:
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.Charisma] = pPacket.ReadInt();
            }

            if (CheckFlag(updateFlag, 0x1000000))
            {
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.Insight] = pPacket.ReadInt();
                didsomething = true;
            }

            if (CheckFlag(updateFlag, 0x2000000))
            {
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.Willpower] = pPacket.ReadInt();
                didsomething = true;
            }

            if (CheckFlag(updateFlag, 0x4000000))
            {
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.CraftDiligence] = pPacket.ReadInt();
                didsomething = true;
            }

            if (CheckFlag(updateFlag, 0x8000000))
            {
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.Empathy] = pPacket.ReadInt();
                didsomething = true;
            }

            if (CheckFlag(updateFlag, 0x10000000))
            {
                pConnection.CharData.Stats.Traits[(int)GW_CharacterStat.TraitVals.Charm] = pPacket.ReadInt();
                didsomething = true;
            }

            if (CheckFlag(updateFlag, 0x20000000))
            {
                pPacket.ReadBytes(21);
            }

            if (CheckFlag(updateFlag, 0x40000000))
            {
                pPacket.ReadByte();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadByte();
            }

            if (CheckFlag(updateFlag, 0x80000000))
            {
                for (byte i = 0; i < 9; i++)
                {
                    pPacket.ReadInt();
                    pPacket.ReadByte();
                    pPacket.ReadInt();
                }
            }

            if (CheckFlag(updateFlag, 0x100000000))
            {
                var value1 = pPacket.ReadByte();
                var value2 = pPacket.ReadByte();
                pConnection.Logger_WriteLine("0x100000000 | {0} | {1}", value1, value2);
            }

            if (CheckFlag(updateFlag, 0x200000000))
            {
                var value = pPacket.ReadInt();
                pConnection.Logger_WriteLine("0x200000000 | {0}", value);
            }

            if (didsomething)
            {
                pConnection.CharData.SaveCharacterInfo(pConnection);

                pConnection.SendTimeUpdate();
            }
        }
 public virtual void HandleSkillMacros(ClientConnection pConnection, MaplePacket pPacket)
 {
     byte count = pPacket.ReadByte();
     if (count == 0) return;
     string q = string.Format("DELETE FROM skillmacros WHERE character_id = {0};\r\n", pConnection.CharacterInternalID);
     q += "INSERT INTO skillmacros VALUES \r\n";
     for (int i = 0; i < count; i++)
     {
         string name = pPacket.ReadString();
         bool shout = pPacket.ReadBool();
         int skill1 = pPacket.ReadInt();
         int skill2 = pPacket.ReadInt();
         int skill3 = pPacket.ReadInt();
         q += string.Format("({0}, {1}, '{2}', {3}, {4}, {5}, {6}),", pConnection.CharacterInternalID, i, MySql.Data.MySqlClient.MySqlHelper.EscapeString(name), shout, skill1, skill2, skill3);
     }
     q = q.TrimEnd(',');
     MySQL_Connection.Instance.RunQuery(q);
 }
Exemple #29
0
        public void Decode(ClientConnection pConnection, MaplePacket pPacket)
        {
            pPacket.Skip(8); // Flag

#if LOCALE_GMS
            pPacket.Skip(1);
#endif

            {
                // Added GMS V.132 
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
            }

#if LOCALE_EMS
            pPacket.Skip(1);
#endif

            int tmp = pPacket.ReadByte();
            pPacket.Skip(tmp * 4);

            tmp = pPacket.ReadInt();
            pPacket.Skip(tmp * (4 + 8));


#if LOCALE_GMS
            pPacket.Skip(1);
#endif

            if (pPacket.ReadBool())
            {
                tmp = pPacket.ReadInt();
                pPacket.Skip(tmp * 8);
                tmp = pPacket.ReadInt();
                pPacket.Skip(tmp * 8);
            }

            Stats = new GW_CharacterStat();
            Stats.Decode(pPacket);

            this.BuddylistSize = pPacket.ReadByte();
#if LOCALE_EMS
            pPacket.ReadByte();
#endif

            if (pPacket.ReadBool()) BlessingOfTheFairy = pPacket.ReadString();
            else BlessingOfTheFairy = null;
            if (pPacket.ReadBool()) BlessingOfEmpress = pPacket.ReadString();
            else BlessingOfEmpress = null;
            if (pPacket.ReadBool()) UltimateExplorer = pPacket.ReadString();
            else UltimateExplorer = null;

            Stats.DecodeMesos(pPacket); // .-.

#if LOCALE_EMS
            pPacket.ReadByte(); // Bool check
            pPacket.ReadInt();
#endif


            // Unknown stuff here

            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadLong();
            }

#if LOCALE_GMS
            // Magical potion pots!!!
            for (int i = pPacket.ReadInt(); i > 0; i--) // V.126
            {
                pPacket.ReadInt(); // Potion pot ID
                pPacket.ReadInt(); // Max value
                pPacket.ReadInt(); // HP
                pPacket.ReadInt(); // ??? (Not max value of MP)
                pPacket.ReadInt(); // MP

                pPacket.ReadLong(); // Start date O.o?
                pPacket.ReadLong(); // End date O.o?
            }
#endif


#if LOCALE_GMS
            // V.142 - RED stuff?

            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadByte();
                pPacket.ReadInt();
                pPacket.ReadInt();
            }

            {
                pPacket.ReadInt();
                for (int i = 3; i > 0; i--)
                {
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                }
            }


            for (int i = pPacket.ReadInt(); i > 0; i--)
                pPacket.ReadInt();

            if (pPacket.ReadBool())
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadLong();
                pPacket.ReadLong();
                pPacket.ReadLong();
            }

            for (int j = 0; j < 2; j++) // called 2 times under each other!
            {
                for (int i = pPacket.ReadByte(); i > 0; i--)
                {
                    pPacket.ReadByte();
                    pPacket.ReadInt();
                    pPacket.ReadByte();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadString();
                }
            }
#endif

#if LOCALE_EMS
            // REMOVED GMS V.141?!
            for (int i = pPacket.ReadInt(); i > 0; i--) // V.137
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt(); 
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
            }

            pPacket.ReadInt();
            for (int i = 6; i > 0; i--)
            {
                pPacket.ReadInt();
            }


            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
            }


            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadString();
            }


            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadString();
            }

#endif

            Inventory = new CharacterInventory();
            Inventory.Decode(pConnection, pPacket);

            //UnknownIntegerListNumber3 = new Dictionary<int, long>();
            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadLong();
                //UnknownIntegerListNumber3.Add(pPacket.ReadInt(), pPacket.ReadLong());
            }

            //UnknownIntegerListNumber4 = new Dictionary<long, long>();
            for (int i = pPacket.ReadInt(); i > 0; i--)
            {
                pPacket.ReadLong();
                pPacket.ReadLong();
                //UnknownIntegerListNumber4.Add(pPacket.ReadLong(), pPacket.ReadLong());
            }


            while (true)
            {
                byte val = pPacket.ReadByte();
                if (val == 0) break;

                {
                    pPacket.ReadInt();
                    pPacket.ReadByte();
                    pPacket.ReadByte();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadInt();
                    pPacket.ReadByte();
                    pPacket.ReadInt();
                    pPacket.ReadLong();
                    pPacket.ReadLong();
                    pPacket.ReadLong();
                    pPacket.ReadLong();
                }
            }


            Skills = new CharacterSkills();
            Skills.Decode(pConnection, pPacket);

            Quests = new CharacterQuests();
            Quests.Decode(pConnection, pPacket);


            // Match
            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
            }


            {

                Rings = new List<Ring>();
                MarriedWith = null;

                // Couple
                for (int i = pPacket.ReadShort(); i > 0; i--)
                {
                    Rings.Add(new Ring(Ring.Type.Couple, pPacket));
                }

                // Friend
                for (int i = pPacket.ReadShort(); i > 0; i--)
                {
                    Rings.Add(new Ring(Ring.Type.Friend, pPacket));
                }

                // Marriage
                for (int i = pPacket.ReadShort(); i > 0; i--)
                {
                    Ring ring = new Ring(Ring.Type.Marriage, pPacket, Stats.Name);
                    Rings.Add(ring);

                    MarriedWith = ring.FriendName;
                }
            }


            Inventory.DecodeTeleportRocks(pPacket);

#if LOCALE_GMS
            Monsterbook = new CharacterMonsterBook();
            Monsterbook.Decode(pPacket);

            pPacket.ReadInt(); // -1?

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.ReadShort();
            }

            {
                // Newyear cards... meh
                // WHAT MEH, SOMEONE HAS THIS FFS D:!!!

                for (short i = pPacket.ReadShort(); i > 0; i--)
                {
                    pPacket.ReadInt(); // Card ID?
                    pPacket.ReadInt(); // Sender ID
                    pPacket.ReadString(); // Sender name
                    pPacket.ReadByte(); // GENDER..?
                    pPacket.ReadLong(); // Sent at?
                    pPacket.ReadInt(); // Receiver ID
                    pPacket.ReadString(); // Receiver name
                    pPacket.ReadByte();
                    pPacket.ReadByte();
                    pPacket.ReadLong(); // Receive date?
                    pPacket.ReadString(); // Message
                }
            }
#else
            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.ReadShort();
                pPacket.ReadString();
            }
#endif

            Quests.DecodePQ(pConnection, pPacket);

            if (GameHelper.IsWildHunter(Stats.JobID))
            {
                pPacket.ReadByte(); // Level

                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt(); // Caught mob
            }

            Quests.DecodePQDone(pConnection, pPacket);

            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                short cnt = pPacket.ReadShort();
                int unk = pPacket.ReadInt(); // 9010040 | Conor (NPC)
                if (cnt > 0 && unk > 0)
                {
                    for (short j = 0; j < cnt; j++)
                    {
                        pPacket.ReadInt(); // 9010040 | Conor (NPC)
                        pPacket.ReadShort();
                        pPacket.ReadInt(); // 4330019 | Pink Coin Purse
                        pPacket.ReadShort();
                    }
                }
            }

            for (int i = 13; i > 0; i--)
            {
                pPacket.ReadInt(); // Stolen Skills
            }

            for (int i = 4; i > 0; i--)
            {
                pPacket.ReadInt(); // Chosen Skills?
            }

            // Inner Stats
            Abilities = new List<Tuple<byte, int, byte>>();
            for (int i = pPacket.ReadShort(); i > 0; i--)
            {
                byte id = pPacket.ReadByte(); // 'ID'
                int skillid = pPacket.ReadInt(); // Skill ID
                byte level = pPacket.ReadByte(); // Level
                pPacket.ReadByte(); // Rank
                Abilities.Add(new Tuple<byte, int, byte>(id, skillid, level));
            }

#if LOCALE_GMS
            {
                // V.134
                for (int i = pPacket.ReadInt(); i > 0; i--)
                {
                    pPacket.ReadString();

                    pPacket.ReadInt();
                    pPacket.ReadString();

                    for (int j = pPacket.ReadInt(); j > 0; j--)
                    {
                        pPacket.ReadByte();
                    }
                }

                pPacket.ReadByte();
            }
#endif

            Stats.HonourLevel = pPacket.ReadInt();
            Stats.HonourExp = pPacket.ReadInt();

            {
                byte unk = pPacket.ReadByte();
                if (unk == 1)
                {
                    while (true)
                    {
                        tmp = pPacket.ReadUShort();
                        if (tmp <= 0) break;

                        while (true)
                        {
                            ushort tmp2 = pPacket.ReadUShort();
                            if (tmp2 <= 0) break;

                            pPacket.ReadInt();
                            pPacket.ReadInt();
                        }
                    }
                }
                else
                {
                    while (true)
                    {
                        tmp = pPacket.ReadUShort();
                        if (tmp <= 0) break;

                        pPacket.ReadUShort();
                        pPacket.ReadInt();
                        pPacket.ReadInt();
                    }
                }
            }

            if (pPacket.ReadBool())
            {
                // Wat.
                ItemBase.DecodeItemData(pConnection, pPacket);
                pPacket.ReadInt();
            }


            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadByte();
            }


            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadLong();
            }

#if LOCALE_EMS
            pPacket.ReadBool();
            pPacket.ReadBool();
#endif
            {
                EvolutionCards = new List<EvolutionCard>();

                for (short i = pPacket.ReadShort(); i > 0; i--)
                {
                    var card = new EvolutionCard();
                    card.Decode(pConnection, pPacket);
                    card.Block = 1;
                    EvolutionCards.Add(card);
                }

                for (short i = pPacket.ReadShort(); i > 0; i--)
                {
                    var card = new EvolutionCard();
                    card.Decode(pConnection, pPacket);
                    card.Block = 2;
                    EvolutionCards.Add(card);
                }

            }

#if LOCALE_EMS
            if (pPacket.ReadBool())
            {
                // Wat.
                ItemBase.DecodeItemData(pConnection, pPacket);
                pPacket.ReadInt();
                pPacket.ReadInt();
            }
#endif

#if LOCALE_EMS
            // No farm info

            for (short i = pPacket.ReadShort(); i > 0; i--)
            {
                pPacket.Skip(20);
            }

#else
            {
                // V.134
                for (byte i = pPacket.ReadByte(); i > 0; i--)
                {
                    pPacket.ReadInt();
                    pPacket.ReadLong();
                }
            }

            {
                // V.134
                // FARM INFO. Creating... = not yet created farm. Else: farmname
                pPacket.ReadString(); // Creating...
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadByte();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();

                pPacket.ReadInt();
                pPacket.ReadInt();
            }

#if LOCALE_GMS
            if (pPacket.ReadBool())
            {
                // Wat.
                ItemBase.DecodeItemData(pConnection, pPacket);
                pPacket.ReadInt();
                pPacket.ReadInt();
            }
#endif

            {
                // V.141
                pPacket.ReadInt();
                pPacket.ReadLong(); // A bit off here, should be filetime value
                pPacket.ReadInt();
            }

            pPacket.Skip(84); // I don't even

            pPacket.ReadByte();

            {
                for (short i = pPacket.ReadShort(); i > 0; i--)
                {
                    pPacket.ReadShort();
                    pPacket.ReadShort();
                }
            }

            {
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();
                pPacket.ReadInt();

                pPacket.Skip(32);
            }

            {
                if (pPacket.ReadInt() > 0)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        pPacket.Skip(4 + 4 + 4);
                        pPacket.ReadString();
                        pPacket.Skip(4 * 7);
                        pPacket.Skip(8 * 4);
                        pPacket.Skip(4 * 4);
                        pPacket.Skip(1 * 5);
                        pPacket.Skip(4 * 3);
                        pPacket.ReadString();
                        pPacket.Skip(4 * 2);
                        pPacket.ReadByte();

                        byte tmptmp = pPacket.ReadByte();
                        if ((tmptmp & 0x01) != 0)
                        {
                            pPacket.ReadInt();
                            pPacket.ReadString();
                            pPacket.Skip(24);
                        }

                        for (int j = pPacket.ReadInt(); j > 0; j++)
                        {
                            pPacket.Skip(4 * 9);
                        }
                    }
                }
            }

            // Removed in V.141
            //pPacket.ReadInt(); // I DONT EVEN D:
#endif
        }
        public virtual void HandleInventoryUpdate(ClientConnection pConnection, MaplePacket pPacket)
        {
            CharacterInventory inventory = pConnection.CharData.Inventory;

            byte type1 = pPacket.ReadByte();
            byte items = pPacket.ReadByte();
            byte type3 = pPacket.ReadByte();
            if (type3 == 0) // Add or update item
            {
                for (var amnt = 0; amnt < items; amnt++)
                {
                    byte type4 = pPacket.ReadByte();
                    byte inv = pPacket.ReadByte();
                    short slot = pPacket.ReadShort();
                    inv -= 1;

                    if (type4 == 0) // New Item
                    {

                        ItemBase item = ItemBase.DecodeItemData(pConnection, pPacket);

                        if (inv == 0)
                        {
                            // Equip
                            byte internalInventory = CharacterInventory.GetEquipInventoryFromSlot(slot);
                            slot = CharacterInventory.CorrectEquipSlot(internalInventory, slot);

                            if (!inventory.EquipmentItems[internalInventory].ContainsKey(slot))
                                inventory.EquipmentItems[internalInventory].Add(slot, item as ItemEquip);
                            else
                                inventory.EquipmentItems[internalInventory][slot] = item as ItemEquip;
                        }
                        else
                        {
                            if (!inventory.InventoryItems[inv - 1].ContainsKey((byte)slot))
                                inventory.InventoryItems[inv - 1].Add((byte)slot, item);
                            else
                                inventory.InventoryItems[inv - 1][(byte)slot] = item;
                        }

                        using (InsertQueryBuilder itemsTable = new InsertQueryBuilder("items"))
                        {
                            itemsTable.OnDuplicateUpdate = true;
                            Queries.SaveItem(pConnection, inv, slot, item, itemsTable);
                            itemsTable.RunQuery();

                        }

                        if (item is ItemPet)
                        {
                            var pet = item as ItemPet;
                            using (InsertQueryBuilder petTable = new InsertQueryBuilder("pets"))
                            {
                                petTable.OnDuplicateUpdate = true;
                                Queries.SavePet(pConnection.CharacterInternalID, pet, petTable);
                                petTable.RunQuery();
                            }
                        }

                    }
                    else if (type4 == 1) // Update amount
                    {
                        short amount = pPacket.ReadShort();
                        if (inv == 0)
                        {
                            pConnection.Logger_WriteLine("WUTWUT"); // Should _never_ happen
                            continue;
                        }

                        ItemBase item = inventory.InventoryItems[inv - 1][(byte)slot];
                        item.Amount = amount;

                        AccountDataCache.Instance.SetChecksumOfSlot(pConnection.CharacterID, pConnection.WorldID, inv, slot, item.GetChecksum());

                        using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                        {
                            itemTable.SetColumn("amount", amount);
                            itemTable.SetColumn("checksum", item.GetChecksum());
                            itemTable.SetWhereColumn("inventory", inv);
                            itemTable.SetWhereColumn("slot", slot);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }


                    }
                    else if (type4 == 2) // Swap
                    {
                        short slotfrom = slot;
                        short slotto = pPacket.ReadShort();

                        bool founditem = false;

                        if (inv == 0)
                        {
                            // Equips!
                            byte internalInventoryFrom = CharacterInventory.GetEquipInventoryFromSlot(slotfrom);
                            byte internalInventoryTo = CharacterInventory.GetEquipInventoryFromSlot(slotto);
                            slotfrom = CharacterInventory.CorrectEquipSlot(internalInventoryFrom, slotfrom);
                            slotto = CharacterInventory.CorrectEquipSlot(internalInventoryTo, slotto);

                            // Switch Equips
                            ItemEquip item = inventory.EquipmentItems[internalInventoryFrom][slotfrom];
                            if (inventory.EquipmentItems[internalInventoryTo].ContainsKey(slotto))
                            {
                                inventory.EquipmentItems[internalInventoryFrom][slotfrom] =
                                    inventory.EquipmentItems[internalInventoryTo][slotto];

                                inventory.EquipmentItems[internalInventoryTo].Remove(slotto); // Remove item
                                founditem = true;
                            }
                            else
                            {
                                inventory.EquipmentItems[internalInventoryFrom].Remove(slotfrom);
                            }
                            inventory.EquipmentItems[internalInventoryTo].Add(slotto, item);
                        }
                        else
                        {
                            // Switch Items
                            ItemBase item = inventory.InventoryItems[inv - 1][(byte)slotfrom];
                            if (inventory.InventoryItems[inv - 1].ContainsKey((byte)slotto))
                            {
                                inventory.InventoryItems[inv - 1][(byte)slotfrom] =
                                    inventory.InventoryItems[inv - 1][(byte)slotto];
                                inventory.InventoryItems[inv - 1].Remove((byte)slotto); // Remove item
                                founditem = true;
                            }
                            else
                            {
                                inventory.InventoryItems[inv - 1].Remove((byte)slotfrom);
                            }
                            inventory.InventoryItems[inv - 1].Add((byte)slotto, item);
                        }

                        if (founditem) // New slot contained item
                        {
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom + 3000);
                                itemTable.SetWhereColumn("inventory", inv);
                                itemTable.SetWhereColumn("slot", slotto);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }

                        using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                        {
                            itemTable.SetColumn("slot", slotto);
                            itemTable.SetWhereColumn("inventory", inv);
                            itemTable.SetWhereColumn("slot", slotfrom);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }

                        if (founditem) // Fix other slot
                        {
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom);
                                itemTable.SetWhereColumn("inventory", inv);
                                itemTable.SetWhereColumn("slot", slotfrom + 3000);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }
                    }
                    else if (type4 == 3)
                    {
                        // Drop/delete item.

                        if (inv == 0)
                        {
                            // Equips!
                            byte internalInventory = CharacterInventory.GetEquipInventoryFromSlot(slot);
                            slot = CharacterInventory.CorrectEquipSlot(internalInventory, slot);

                            if (inventory.EquipmentItems[internalInventory].ContainsKey(slot))
                            {
                                inventory.EquipmentItems[internalInventory].Remove(slot);
                                AccountDataCache.Instance.DeleteItemChecksum(pConnection, 0, slot);
                            }
                            else
                                pConnection.Logger_WriteLine("!!! Could not find item @ {0} {1}", inv, slot);
                        }
                        else
                        {
                            if (inventory.InventoryItems[inv - 1].ContainsKey((byte)slot))
                            {
                                inventory.InventoryItems[inv - 1].Remove((byte)slot);
                                AccountDataCache.Instance.DeleteItemChecksum(pConnection, (ushort)(inv - 1), slot);
                            }
                            else
                                pConnection.Logger_WriteLine("!!! Could not find item @ {0} {1}", inv, slot);


                        }

                        using (DeleteQueryBuilder itemTable = new DeleteQueryBuilder("items"))
                        {
                            itemTable.SetWhereColumn("inventory", inv);
                            itemTable.SetWhereColumn("slot", slot);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);
                            itemTable.RunQuery();
                        }
                    }

                    else if (type4 == 4)
                    {
                        pPacket.ReadLong(); // Unknown..?
                    }
                    else if (type4 == 5)
                    {
                        // 'Swap' items from and to bags
                        inv -= 1;

                        short from = slot;
                        byte slotfrom = (byte)(from % 100);
                        byte bagfrom = (byte)(from / 100);

                        short to = pPacket.ReadShort();
                        byte slotto = (byte)(to % 100);
                        byte bagto = (byte)(to / 100);


                        slotfrom -= 1;
                        slotto -= 1;
                        if (bagto == 0)
                            bagto = 255;
                        else
                            bagto -= 1;
                        if (bagfrom == 0)
                            bagfrom = 255;
                        else
                            bagfrom -= 1;


                        ushort invto = bagto == 255 ? inv : GameHelper.GetBagID(bagto, inv);
                        ushort invfrom = bagfrom == 255 ? inv : GameHelper.GetBagID(bagfrom, inv);


                        if (
                            (bagfrom != 255 && bagto != 255) ||
                            (bagfrom == bagto) || // Check if the item is being moved to itself or something

                            (bagfrom == 255 && !inventory.InventoryItems[inv].ContainsKey(slotfrom)) ||
                            (bagfrom != 255 && (!inventory.BagItems.ContainsKey(invfrom) || !inventory.BagItems[invfrom].Items.ContainsKey(slotfrom))) ||

                            (bagto != 255 && !inventory.BagItems.ContainsKey(invto)) // Only check if bag exists
                            )
                        {
                            pConnection.Logger_WriteLine("Invalid item movement in bag !!!");
                            continue;
                        }

                        bool founditem = false;
                        if (bagfrom == 255)
                        {
                            // Move to bag
                            ItemBase ib = inventory.InventoryItems[inv][slotfrom];
                            if (inventory.BagItems[invto].Items.ContainsKey(slotto))
                            {
                                inventory.InventoryItems[inv][slotfrom] = inventory.BagItems[invto].Items[slotto];
                                inventory.BagItems[invto].Items.Remove(slotto);
                                founditem = true;
                            }

                            inventory.BagItems[invto].Items.Add(slotto, ib);



                        }
                        else
                        {
                            // Move to normal slot
                            ItemBase ib = inventory.BagItems[invfrom].Items[slotfrom];
                            if (inventory.InventoryItems[inv].ContainsKey(slotto))
                            {
                                inventory.BagItems[invfrom].Items[slotfrom] = inventory.InventoryItems[inv][slotto];
                                inventory.InventoryItems[inv].Remove(slotto);
                            }

                            inventory.InventoryItems[inv].Add(slotto, ib);



                            using (InsertQueryBuilder itemsTable = new InsertQueryBuilder("items"))
                            {
                                itemsTable.OnDuplicateUpdate = true;
                                Queries.SaveItem(pConnection, inv, slot, ib, itemsTable);
                                itemsTable.RunQuery();
                            }


                        }

                        /*
                         * Item A: item being used to move/swap | inv 3, slot 21 (Etc) | slotfrom, invfrom
                         * Item B: item that is being swapped with A | inv 11, slot 3 (Bag 2) | slotto, invto
                         * 
                         * Move B to a temp slot, to the new inventory: inv 11 -> inv 3, slot 3 -> slot 3021
                         * Move A to B: inv 3 -> inv 11, slot 21 -> slot 3
                         * Move B to A: slot 3021 -> slot 21
                         * 
                        */


                        if (founditem) // New slot contained item
                        {
                            // Temporary moving item
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom + 3000);
                                itemTable.SetColumn("inventory", invfrom);
                                itemTable.SetWhereColumn("inventory", invto);
                                itemTable.SetWhereColumn("slot", slotto);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }

                        using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                        {
                            itemTable.SetColumn("slot", slotto);
                            itemTable.SetColumn("inventory", invto);
                            itemTable.SetWhereColumn("inventory", invfrom);
                            itemTable.SetWhereColumn("slot", slotfrom);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }

                        if (founditem) // Fix other slot
                        {
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom);
                                itemTable.SetWhereColumn("inventory", invfrom);
                                itemTable.SetWhereColumn("slot", slotfrom + 3000);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }
                    }
                    else if (type4 == 6)
                    {
                        // Update bag item amount
                        inv -= 1;

                        short from = slot;
                        byte slotfrom = (byte)(from % 100);
                        byte bagfrom = (byte)(from / 100);

                        short amount = pPacket.ReadShort();


                        slotfrom -= 1;
                        if (bagfrom == 0)
                        {
                            pConnection.Logger_WriteLine("Invalid item bag!");
                            continue;
                        }
                        else
                            bagfrom -= 1;

                        ushort invfrom = GameHelper.GetBagID(bagfrom, inv);

                        if (
                            !inventory.BagItems.ContainsKey(invfrom) || !inventory.BagItems[invfrom].Items.ContainsKey(slotfrom)
                            )
                        {
                            pConnection.Logger_WriteLine("Invalid item movement in bag (item did not exist)!!!");
                            continue;
                        }



                        ItemBase item = inventory.BagItems[invfrom].Items[slotfrom];
                        item.Amount = amount;

                        AccountDataCache.Instance.SetChecksumOfSlot(pConnection.CharacterID, pConnection.WorldID, inv, slot, item.GetChecksum());

                        using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                        {
                            itemTable.SetColumn("amount", amount);
                            itemTable.SetColumn("checksum", item.GetChecksum());
                            itemTable.SetWhereColumn("inventory", invfrom);
                            itemTable.SetWhereColumn("slot", slot);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }
                    }
                    else if (type4 == 7)
                    {
                        // Delete/drop bag item D:
                        inv -= 1;

                        short from = slot;
                        byte slotfrom = (byte)(from % 100);
                        byte bagfrom = (byte)(from / 100);

                        slotfrom -= 1;
                        bagfrom -= 1;
                        ushort invfrom = GameHelper.GetBagID(bagfrom, inv);


                        using (DeleteQueryBuilder itemTable = new DeleteQueryBuilder("items"))
                        {
                            itemTable.SetWhereColumn("inventory", invfrom);
                            itemTable.SetWhereColumn("slot", slotfrom);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }
                    }
                    else if (type4 == 8)
                    {
                        // Swap/move item in bags
                        inv -= 1;

                        short from = slot;
                        byte slotfrom = (byte)(from % 100);
                        byte bagfrom = (byte)(from / 100);

                        short to = pPacket.ReadShort();
                        byte slotto = (byte)(to % 100);
                        byte bagto = (byte)(to / 100);

                        slotfrom -= 1;
                        slotto -= 1;
                        bagto -= 1;
                        bagfrom -= 1;


                        ushort invto = GameHelper.GetBagID(bagto, inv);
                        ushort invfrom = GameHelper.GetBagID(bagfrom, inv);


                        if (!inventory.BagItems.ContainsKey(invfrom) || !inventory.BagItems.ContainsKey(invto))
                        {
                            pConnection.Logger_WriteLine("Invalid item movement in bag");
                            continue;
                        }

                        if (!inventory.BagItems[invfrom].Items.ContainsKey(slotfrom))
                        {
                            pConnection.Logger_WriteLine("Invalid item movement in bag (item not found)");
                            continue;
                        }

                        ItemBase item = inventory.BagItems[invfrom].Items[slotfrom];

                        bool founditem = false;

                        if (inventory.BagItems[invto].Items.ContainsKey(slotto))
                        {
                            // Swap

                            inventory.BagItems[invfrom].Items[slotfrom] = inventory.BagItems[invto].Items[slotto];
                            inventory.BagItems[invto].Items.Remove(slotto); // Delete item
                            founditem = true;
                        }
                        inventory.BagItems[invto].Items.Add(slotto, item);




                        if (founditem) // New slot contained item
                        {
                            // Temporary moving item
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom + 3000);
                                itemTable.SetColumn("inventory", invfrom);
                                itemTable.SetWhereColumn("inventory", invto);
                                itemTable.SetWhereColumn("slot", slotto);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }

                        using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                        {
                            itemTable.SetColumn("slot", slotto);
                            itemTable.SetColumn("inventory", invto);
                            itemTable.SetWhereColumn("inventory", invfrom);
                            itemTable.SetWhereColumn("slot", slotfrom);
                            itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                            MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                        }

                        if (founditem) // Fix other slot
                        {
                            using (UpdateQueryBuilder itemTable = new UpdateQueryBuilder("items"))
                            {
                                itemTable.SetColumn("slot", slotfrom);
                                itemTable.SetWhereColumn("inventory", invfrom);
                                itemTable.SetWhereColumn("slot", slotfrom + 3000);
                                itemTable.SetWhereColumn("character_id", pConnection.CharacterInternalID);

                                MySQL_Connection.Instance.RunQuery(itemTable.ToString());
                            }
                        }
                    }
                    else if (type4 == 9)
                    {
                        // Add item directly to bag
                        inv -= 1;

                        ItemBase item = ItemBase.DecodeItemData(pConnection, pPacket);

                        short from = slot;
                        byte slotfrom = (byte)(from % 100);
                        byte bagfrom = (byte)(from / 100);

                        slotfrom -= 1;
                        bagfrom -= 1;
                        ushort invfrom = GameHelper.GetBagID(bagfrom, inv);

                        if (!inventory.BagItems.ContainsKey(invfrom)) continue;

                        inventory.BagItems[invfrom].Items[slotfrom] = item;


                        using (InsertQueryBuilder itemsTable = new InsertQueryBuilder("items"))
                        {
                            itemsTable.OnDuplicateUpdate = true;
                            Queries.SaveItem(pConnection, invfrom, slotfrom, item, itemsTable);
                            itemsTable.RunQuery();

                        }
                        if (item is ItemPet)
                        {
                            var pet = item as ItemPet;
                            using (InsertQueryBuilder petTable = new InsertQueryBuilder("pets"))
                            {
                                petTable.OnDuplicateUpdate = true;
                                Queries.SavePet(pConnection.CharacterInternalID, pet, petTable);
                                petTable.RunQuery();
                            }
                        }
                    }
                    else if (type4 == 10)
                    {
                        pConnection.Logger_WriteLine("Player probably removed some bag item... O.o?");
                    }
                }
            }
            pConnection.SendTimeUpdate();
        }