Beispiel #1
0
        /*
         * // query packet
         * 79 32 00 00
         * 49 6D 70 20 4D 69 6E 69 6F 6E 00   // name
         * 00
         * 00
         * 00
         * 43 43 43 43 43 43 43 43 43 43 43 43 43 43 00  // guild name
         * 06 00 10 00 // flags1
         * 00 00 00 00
         * 04 00 00 00 // type
         * 02 00 00 00 // unk4
         * 00 00 00 00
         * 00 00 00 00
         *
         * // MSG_CORPSE_QUERY
         * // {01 00 00 00 00 8F 56 D1 44 7B AE D1 44 0A 57 F3 42 00 00 00 00 }
         */

        void CreatureQuery(OP code, PlayerConnection c)
        {
            uint  entry;
            ulong guid;

            c.Seek(2).Get(out entry).Get(out guid);

            Hashtable data = gameServer.DB.creatures.Get("creature " + entry.ToString());

            if (data == null)
            {
                gameServer.LogMessage("CreatureQuery code not found! : " + code + " entry: " + entry + "  guid:" + guid);
                return;
            }
            gameServer.LogMessage("CreatureQuery code: " + code + " entry: " + entry + "  guid:" + guid);

            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add(entry);
            pack.Add(data["name"] as string);
            if (data.Contains("name2"))
            {
                pack.Add(data["name2"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            if (data.Contains("name3"))
            {
                pack.Add(data["name3"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            if (data.Contains("name4"))
            {
                pack.Add(data["name4"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            if (data.Contains("guild"))
            {
                pack.Add(data["guild"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            pack.Add(Get(data, "flags1", 0));
            pack.Add((uint)0);
            pack.Add(Get(data, "type", 0));
            pack.Add(Get(data, "unk4", 0));
            pack.Add((uint)0);
            pack.Add((uint)0);
            c.Send(OP.SMSG_CREATURE_QUERY_RESPONSE, pack);
        }
Beispiel #2
0
        public virtual byte[] GetSaveData()
        {
            ByteArrayBuilder pack = new ByteArrayBuilder();

            pack.Add(mdurability).Add(durability).Add(stackcount).Add(flags).Add((uint)0);
            return(pack);
        }
Beispiel #3
0
        public void BuildUpdate(ByteArrayBuilder pack)
        {
            if (data == null)
            {
                pack.Add((byte)0);
                return;
            }
            int zero = 0;

            for (int i = data.Length - 1; i > 0; i--)
            {
                if (data[i] == 0)
                {
                    zero++;
                }
                else
                {
                    break;
                }
            }
            pack.Add((byte)(data.Length - zero));
            for (int i = 0; i < data.Length - zero; i++)
            {
                pack.Add(data[i]);
            }
        }
Beispiel #4
0
        void TimeQuery(OP code, PlayerConnection c)
        {
            //gameServer.LogMessage("TimeQuery: code: " + code);
            ByteArrayBuilder b = new ByteArrayBuilder(false);

            b.Add(Const.GetTimeStamp());
            c.Send(OP.SMSG_QUERY_TIME_RESPONSE, b);
        }
Beispiel #5
0
        public void Login(PlayerConnection c)
        {
            conn        = c;
            conn.player = this;

            SetMessageHandler();

            Send(OP.SMSG_ACCOUNT_DATA_MD5, new byte[80]);

            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add(Pos.x);
            pack.Add(Pos.y);
            pack.Add(Pos.z);
            pack.Add((uint)Zone);
            pack.Add((uint)Map);
            Send(OP.SMSG_BINDPOINTUPDATE, pack);
            pack.Length = 0;

            Send(OP.SMSG_TUTORIAL_FLAGS, tutorialFlags);

            BuildSpellData(pack);
            Send(OP.SMSG_INITIAL_SPELLS, pack);
            pack.Length = 0;

            Send(OP.SMSG_ACTION_BUTTONS, new byte[480]);

            pack.Add((uint)64);
            for (int i = 0; i < 64; i++)
            {
                if (i == 0)
                {
                    pack.Add((uint)3);
                }
                else
                {
                    pack.Add((uint)1);
                }
                pack.Add((byte)0);
            }
            Send(OP.SMSG_INITIALIZE_FACTIONS, pack);
            pack.Length = 0;

            pack.Add(Const.GetTimeStamp());
            pack.Add(0.017f);
            Send(OP.SMSG_LOGIN_SETTIMESPEED, pack);
            pack.Length = 0;

            // clear all items update flag
            BuildUpdateForSet();
            updatePacket.Clear();

            BuildCreateMask(updateMask, true);
            SendUpdate(BuildUpdate(updateMask, UpdateType.All, true));
            SendCreateItems(this, CreateItemType.Self);
            SendUpdate();
            tickRemove = 0;
        }
Beispiel #6
0
        public byte[] BuildUpdate(UpdateMask mask, UpdateType type, bool bControl)
        {
            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add((byte)type);
            pack.Add(GUID);

            if (type != UpdateType.Value)           // buildMoveType
            {
                pack.Add((byte)ObjectType);
                BuildMovementUpdate(pack);
            }

            if (type == UpdateType.All)
            {
                if (bControl)
                {
                    pack.Add((uint)1);
                }
                else
                {
                    pack.Add((uint)0);
                }

                pack.Add((uint)1);
                pack.Add((uint)0);                   // timeid
                pack.Add((uint)0);                   // victim
                pack.Add((uint)0);
            }

            if (type != UpdateType.Move)           // have update value
            {
                mask.BuildUpdate(pack);
                for (ushort idx = 0; idx < mask.Length; idx++)
                {
                    if (mask.Set(idx, false))
                    {
                        if (idx >= updateValues.Count)
                        {
                            pack.Add((uint)0);
                        }
                        else if (updateValues[idx] is uint)
                        {
                            pack.Add((uint)updateValues[idx]);
                        }
                        else
                        {
                            pack.Add((float)updateValues[idx]);
                        }
                    }
                }
            }

            return(pack);
        }
Beispiel #7
0
        public bool ItemError(ItemErrorNo no)
        {
            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add((byte)no);
            pack.Add(itemErrorGUID1);
            pack.Add(itemErrorGUID2);
            pack.Add((byte)0);
            Send(OP.SMSG_INVENTORY_CHANGE_FAILURE, pack);
            return(false);
        }
Beispiel #8
0
        protected virtual void BuildMovementUpdate(ByteArrayBuilder pack)
        {
            //pack.Add( new uint[12] );
            pack.Add((uint)0, 0, 0, 0, 0, 0); // flags

            pack.Add(2.5);                    // walk speed
            pack.Add(7.0);                    // run speed
            pack.Add(2.5);                    // backward speed
            pack.Add(4.7);
            pack.Add(4.5);
            pack.Add(3.14159);
        }
Beispiel #9
0
        protected override void BuildMovementUpdate(ByteArrayBuilder pack)
        {
            pack.Add((uint)0, 0);               // flags
            pack.Add(Pos.x, Pos.y, Pos.z, Orientation);

            pack.Add(2.5);               // walk speed
            pack.Add(7.0);               // run speed
            pack.Add(2.5);               // backward speed
            pack.Add(4.7);
            pack.Add(4.5);
            pack.Add(3.14159);
        }
Beispiel #10
0
 public void Send(byte[] b)
 {
     if (b == null)
     {
         return;
     }
     if (result == null)
     {
         result = new ByteArrayBuilder();
     }
     result.Add(b);
 }
        public void GetRealmList(string nm, ByteArrayBuilder pack)
        {
            Hashtable user = accounts.Get(nm.ToLower());

            if (user == null)
            {
                pack.Add((byte)0);
                return;
            }

            pack.Add((byte)servers.Count);
            foreach (string svr in servers.Keys)
            {
                Hashtable h = servers[svr] as Hashtable;

                if (((string)h["Type"]).ToLower() == "pvp")
                {
                    pack.Add((uint)1);
                }
                else
                {
                    pack.Add((uint)0);
                }

                //
                int tick = (int)h["UpdateTick"];
                if (Const.Tick - tick > 30 * 1000)
                {
                    pack.Add((byte)1);
                }
                else
                {
                    pack.Add((byte)0);  // 0 - green, 1 - red, 2 - grey (offline)*/
                }
                pack.Add(svr);          // Jmeno serveru

                pack.Add((string)h["Address"]);
                //h["UserCount"];
                pack.Add((uint)0);                  // Pripojenych uzivatelu nebo timezone?

                string charnm = "CHAR " + svr;      // pocet postav na accountu
                if (user.Contains(charnm))
                {
                    pack.Add((byte)((string)user[charnm]).Split(' ').Length);
                }
                else
                {
                    pack.Add((byte)0);
                }
                pack.Add((byte)0, 0);                // Prvni byte je narodnost serveru 0,1 - english atd.. Druhy byte meni pozadi pro postavy pouze kdyz je postav 0
            }
        }
Beispiel #12
0
        public bool ServerMessage(string text, uint type, Character c)
        {
            ByteArrayBuilder pack = new ByteArrayBuilder();

            pack.Add((byte)type);
            pack.Add((uint)(text.Length));
            pack.Add((byte)1);
            pack.Add(text);
            //  pack.Add((byte)0);
            c.Send(OP.SMSG_SERVER_MESSAGE, pack);

            return(true);
        }
        void ChannelNotify(PlayerConnection c, string chnl, byte type, uint data)
        {
            ByteArrayBuilder pack = new ByteArrayBuilder();

            pack.Add(type);
            pack.Add(chnl);
            if (type == 2)
            {
                pack.Add(data);
            }


            c.Send(OP.SMSG_CHANNEL_NOTIFY, pack);
        }
 void Encode(ByteArrayBuilder data)
 {
     for (int t = 0; t < 4; t++)
     {
         byte a = key[3];
         a = (byte)(SS_Hash[a] ^ data[t]);
         byte d = key[2];
         a      += d;
         data[t] = a;
         key[2]  = a;
         a       = key[3];
         a++;
         key[3] = (byte)(a % 0x28);
     }
 }
Beispiel #15
0
        public void Wall(string msg)
        {
            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add((byte)CHAT.SYSTEM)
            .Add((uint)0, 0, 0, 0);
            pack.Add(msg);
            pack.Add((byte)0);
            pack.Set(13, (ushort)(pack.Length - 18));

            foreach (Character c in GetOnline())
            {
                c.Send(OP.SMSG_MESSAGECHAT, pack);
            }
        }
Beispiel #16
0
        byte[] GetItemsSaveData()
        {
            ByteArrayBuilder pack = new ByteArrayBuilder();

            for (int i = 0; i < items.Length; i++)
            {
                if (items[i] == null)
                {
                    continue;
                }
                pack.Add((byte)i).Add(items[i].Entry);

                int pos = pack.Length;
                pack.Add((ushort)0);
                pack.Add(items[i].GetSaveData());
                pack.Set(pos, (ushort)(pack.Length - pos - 2));
            }
            return(pack);
        }
        void Decode(ByteArrayBuilder data)
        {
            for (int t = 0; t < 6; t++)
            {
                byte a = key[0];
                key[0] = data[t];

                byte b = data[t];
                b = (byte)(b - a);

                byte d = key[1];
                a       = SS_Hash[d];
                a       = (byte)(a ^ b);
                data[t] = a;

                a = key[1];
                a++;
                key[1] = (byte)(a % 0x28);
            }
        }
Beispiel #18
0
        public virtual void Regen()
        {
            if (spawnPoint != null && tickAutoMove <= Const.Tick)
            {
                Path    path      = new Path();         // trida v utility
                float[] movePoint = spawnPoint.spawnDist;

                if (movePoint.Length == 2 && movePoint[0] > 1)                // random move
                {
                    path.Add(new MapPosition(Pos, 0));
                    Position pos;
                    //while(path.TotalLength() < movePoint[1]*2)
                    float dist = 0;
                    do
                    {
                        gameServer.PPoint.GetDest(spawnPoint.map, spawnPoint.point, Const.rand.Next(6), Const.rand.Next((int)movePoint[0]), out pos);
                        dist = pos.Distance(spawnPoint.point);
                    } while(dist > (int)movePoint[0] || dist < 1);
                    path.Add(new MapPosition(pos, 0));
                }
                if (movePoint.Length >= 3)
                {
                }
                if (path.Count > 0)
                {
                    tickAutoMove = (int)(path.TotalLength() / 2.5 * 1000);
                    path.RemoveAt(0);

                    ByteArrayBuilder pack = new ByteArrayBuilder(false);
                    pack.Add(GUID).Add(Pos.x).Add(Pos.y).Add(Pos.z).Add(Orientation);
                    pack.Add(new byte[5]);
                    pack.Add((uint)tickAutoMove, (uint)path.Count);
                    pack.Add(path.Data());
                    SendMessageToSet(OP.SMSG_MONSTER_MOVE, pack, false);

                    tickAutoMove += Const.Tick + 1500;

                    Pos = path[path.Count - 1].Pos;
                }
            }
        }
Beispiel #19
0
        public override void RunSend()
        {
            if (result == null)
            {
                return;
            }
            int sz = sock.Send(result);

            if (sz <= 0)
            {
                Dispose();
                return;
            }
            if (result.Length > sz)
            {
                result.Remove(0, sz);
                return;
            }
            result = null;
            return;
        }
Beispiel #20
0
        void NameQuery(OP code, PlayerConnection c)
        {
            uint guid;

            c.Seek(2).Get(out guid);

            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add(guid, 0);

            byte   race, gender, cls;
            string nm = gameServer.GetCharacter(guid, out race, out gender, out cls);

            if (nm != null)
            {
                pack.Add(nm).Add((uint)race, (uint)gender, (uint)cls);
            }
            else
            {
                pack.Add("Unknown").Add((uint)0, 0, 0);
            }
            c.Send(OP.SMSG_NAME_QUERY_RESPONSE, pack);
        }
Beispiel #21
0
        public override byte[] GetSaveData()
        {
            ByteArrayBuilder pack = new ByteArrayBuilder();

            pack.Add(base.GetSaveData());

            for (int i = 0; i < items.Length; i++)
            {
                if (items[i] == null)
                {
                    continue;
                }
                pack.Add((byte)i);

                pack.Add(items[i].Entry);

                int pos = pack.Length;
                pack.Add((ushort)0);
                pack.Add(items[i].GetSaveData());
                pack.Set(pos, (ushort)(pack.Length - pos - 2));
            }
            pack.Add((byte)SlotID.CHARACTER);
            return(pack);
        }
Beispiel #22
0
        public virtual void UpdateInRange(ICollection allObjs, ArrayList objRemove)
        {
            // check someone exit
            ArrayList obExit = new ArrayList();

            foreach (ObjWithPosition ob in objectInRange)
            {
                if (objRemove.Contains(ob) || ob.mapID != mapID || Distance(ob) > Const.UPDATE_DISTANCE)
                {
                    obExit.Add(ob);
                }
            }
            foreach (ObjWithPosition ob in obExit)
            {
                objectInRange.Remove(ob);
                ob.objectInRange.Remove(this);

                if (IsType(TYPE.PLAYER))                 // send Exit Message
                {
                    ByteArrayBuilder b = new ByteArrayBuilder(false);
                    b.Add(ob.GUID);
                    (this as Character).Send(OP.SMSG_DESTROY_OBJECT, b);
                }

                if (ob.IsType(TYPE.PLAYER))
                {
                    ByteArrayBuilder b = new ByteArrayBuilder(false);
                    b.Add(GUID);
                    (ob as Character).Send(OP.SMSG_DESTROY_OBJECT, b);
                }
            }

            // check me join
            if (Pos.Distance(lastUpdatePos) < Const.UPDATE_DISTANCE / 10)
            {
                return;
            }
            if (IsType(TYPE.PLAYER))
            {
                Character c = this as Character;
                if (!c.InWorld())
                {
                    return;
                }
                gameServer.RefrencePosition(this);
            }

            lastUpdatePos = Pos;
            foreach (ObjWithPosition ob in allObjs)
            {
                if (ob.mapID != mapID || ob == this)
                {
                    continue;
                }
                if (obExit.Contains(ob) || objectInRange.Contains(ob) || Distance(ob) > Const.UPDATE_DISTANCE)
                {
                    continue;
                }

                if (ob.IsType(TYPE.PLAYER) && !(ob as Character).InWorld())
                {
                    continue;
                }

                if (CanSee(ob))
                {
                    objectInRange.Add(ob);

                    if (IsType(TYPE.PLAYER))                     // send ob Join Message
                    {
                        UpdateMask mask = new UpdateMask();
                        ob.BuildCreateMask(mask, false);
                        (this as Character).SendUpdate(ob.BuildUpdate(mask, UpdateType.All, false));

                        if (ob.IsType(TYPE.PLAYER))
                        {
                            (this as Character).SendCreateItems(ob as Character, CreateItemType.Other);
                        }
                    }
                }

                if (ob.CanSee(this))
                {
                    ob.objectInRange.Add(this);

                    if (ob.IsType(TYPE.PLAYER))                     // send ob Join Message
                    {
                        UpdateMask mask = new UpdateMask();
                        BuildCreateMask(mask, false);
                        (ob as Character).SendUpdate(BuildUpdate(mask, UpdateType.All, false));

                        if (IsType(TYPE.PLAYER))
                        {
                            (ob as Character).SendCreateItems(this as Character, CreateItemType.Other);
                        }
                    }
                }
            }
        }
Beispiel #23
0
 public virtual void GetSaveData(ByteArrayBuilder data)
 {
 }
        public void Send(OP code, byte[] data)
        {
            if (sock == null)
            {
                return;
            }

            #region debug
#if DEBUG
            //    StreamWriter w=new StreamWriter("d:\\msend.txt", true);
            StreamWriter  w   = new StreamWriter("c:\\msend.txt", true);
            StringBuilder str = new StringBuilder();

            byte[] cdata = data;
            if (code == OP.SMSG_COMPRESSED_UPDATE_OBJECT)
            {
                ICSharpCode.SharpZipLib.Zip.Compression.Inflater inflater = new ICSharpCode.SharpZipLib.Zip.Compression.Inflater();
                inflater.SetInput(data, 4, data.Length - 4);

                cdata = new byte[data[0] + data[1] * 256 + data[2] * 256 * 256];
                inflater.Inflate(cdata);
                //  ZLib.Decompress(cdata);
            }

            str.AppendFormat("[{0} {1}] {2} length={3} ", Const.Tick, sock.RemoteEndPoint.ToString(), code, cdata.Length);
            if (code == OP.SMSG_UPDATE_OBJECT || code == OP.SMSG_COMPRESSED_UPDATE_OBJECT)
            {
                int pos = 5;
                str.AppendFormat("count={0}\r\n", cdata[0]);
                for (int i = 0; i < cdata[0]; i++)
                {
                    if (pos >= cdata.Length)
                    {
                        break;
                    }

                    byte type = cdata[pos];
                    str.AppendFormat(" {0} TYPE={1} GUID={2:X} ", i + 1, type, BitConverter.ToUInt32(cdata, pos + 1));
                    pos += 9;

                    if (type > 0)
                    {
                        byte obtype = cdata[pos]; pos += 9;
                        str.AppendFormat("OBTYPE={0} MOVE [", obtype);
                        for (int j = 0; j < 10; j++)
                        {
                            str.AppendFormat("{0} ", BitConverter.ToSingle(cdata, pos));
                            pos += 4;
                        }
                        pos += 20;
                        str.AppendFormat("] ");
                    }
                    str.AppendFormat("UPDATE [");
                    byte cnt  = cdata[pos]; pos++;
                    int  cpos = pos; pos += cnt * 4;
                    for (int j = 0; j < cnt * 32; j++)
                    {
                        if ((cdata[cpos + j / 8] & (1 << (j % 8))) != 0)
                        {
                            if (pos >= cdata.Length)
                            {
                                break;
                            }

                            str.AppendFormat("{0}={1:X} ", j, BitConverter.ToUInt32(cdata, pos));
                            pos += 4;
                        }
                    }
                    str.AppendFormat("]\r\n");
                }
                str.Length = str.Length - 2;
            }             //
            else
            {
                str.Append("{ ");
                for (int i = 0; i < data.Length; i++)
                {
                    string s = data[i].ToString("X");
                    if (s.Length == 2)
                    {
                        str.Append(s + " ");
                    }
                    else
                    {
                        str.Append("0" + s + " ");
                    }
                }
                str.Append("}");
            }

            w.WriteLine(str.ToString());
            w.Close();
#endif
            #endregion
            ByteArrayBuilder pack = new ByteArrayBuilder();
            pack.Add((ushort)(data.Length + 2));
            pack.Add((byte)code, (byte)((ushort)code >> 8));
            pack.Add(data);
            if (SS_Hash != null)
            {
                Encode(pack);
            }
            Send(pack);
        }
Beispiel #25
0
        public bool CreateNew(PlayerConnection conn, string n)
        {
            Name = n;
            Console.WriteLine(n);
            conn.Get(out race).Get(out class_).Get(out gender).
            Get(out skin).Get(out face).Get(out hairStyle).Get(out hairColor).Get(out facialHair).Get(out outfitId);

            Console.WriteLine("CMSG_CHAR_CREATE {0}/{1} {2} {3} {4} {5} {6} {7} {8} {9} {10}",
                              conn.userName, n, race, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId);

            for (int i = 0; i < tutorialFlags.Length; i++)
            {
                tutorialFlags[i] = 0xff;
            }

            Hashtable r = gameServer.DB.classes.Get("race " + race.ToString());

            if (r == null)
            {
                return(false);
            }
            else
            {
                mapID  = (ushort)(int)r["startmap"];
                zoneID = (ushort)(int)r["startzone"];

                float[] xyz = r["startpos"] as float[];
                Pos.x       = xyz[0];
                Pos.y       = xyz[1];
                Pos.z       = xyz[2];
                Orientation = xyz[3];

                /*Console.WriteLine("Startmap:" + r["startmap"] );
                 * Console.WriteLine("startzone:" + r["startzone"]);
                 * Console.WriteLine("startpos: {0}, {1}, {2}, {3} ", xyz[0], xyz[1], xyz[2], xyz[3]);*/


                int[] sstat = r["startstats"] as int[];
                for (int i = 0; i < stat.Length; i++)
                {
                    stat[i] = (byte)sstat[i];
                }

                if (gender > 0)
                {
                    displayID = (uint)(int)r["bodyfemale"];
                }
                else
                {
                    displayID = (uint)(int)r["bodymale"];
                }

                int[] skills = r["skill"] as int[];
                for (int i = 0; i < skills.Length - 2; i += 3)
                {
                    AddSkill(skills[i], skills[i + 1], skills[i + 2]);
                }

                int[] spells = r["spell"] as int[];
                foreach (int sp in spells)
                {
                    AddSpell((uint)sp);
                }
            }

            r = gameServer.DB.classes.Get("class " + class_.ToString());
            if (r != null)
            {
                int[] sstat = r["startstats"] as int[];
                for (int i = 0; i < stat.Length; i++)
                {
                    stat[i] += (byte)sstat[i];
                }

                health = mhealth = (uint)(int)r["health"];

                int[] maxpowers = r["maxpowers"] as int[];
                for (int i = 0; i < mpower.Length; i++)
                {
                    power[i] = mpower[i] = (uint)maxpowers[i];
                    if (power[i] > 0)
                    {
                        powerType = (PowerType)i;
                    }
                }

                int[] attackTime = r["attacktime"] as int[];
                attackTime0 = (uint)attackTime[0];
                attackTime1 = (uint)attackTime[1];

                // ...

                int[] skills = r["skill"] as int[];
                for (int i = 0; i < skills.Length - 2; i += 3)
                {
                    AddSkill(skills[i], skills[i + 1], skills[i + 2]);
                }

                int[] spells = r["spell"] as int[];
                foreach (int sp in spells)
                {
                    AddSpell((uint)sp);
                }
            }
            else
            {
                return(false);
            }
            r = gameServer.DB.classes.Get(String.Format("startitems {0} {1}", race, class_));
            if (r == null)
            {
                return(false);
            }

            ByteArrayBuilder items = new ByteArrayBuilder();

            int[] its = r["item"] as int[];
            for (int i = 0; i < its.Length - 1; i += 2)
            {
                items.Add((byte)its[i]);                 // slot
                items.Add((uint)its[i + 1]);             // entry
                items.Add((ushort)0);                    // addition data
            }
            items.pos = 0;
            return(Create((ByteArrayBase)items));
        }
Beispiel #26
0
        public byte[] GetSaveData()
        {
            Hashtable h = new Hashtable();

            ByteArrayBuilder b = new ByteArrayBuilder();

            b.Add(race, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId);
            h["Base"] = (byte[])b;
            b.Length  = 0;

            b.Add(Map, Zone);
            b.Add(Pos.x, Pos.y, Pos.z, Orientation);
            h["Position"] = (byte[])b;
            b.Length      = 0;

            h["TutorialFlags"] = tutorialFlags;

            for (int i = 0; i < stat.Length; i++)
            {
                stat[i] -= (byte)nstat[i];
            }
            h["Stat"] = stat;
            for (int i = 0; i < stat.Length; i++)
            {
                stat[i] += (byte)nstat[i];
            }

            mhealth = (uint)(mhealth - nhealth);
            if (powerType == PowerType.MANA)
            {
                mpower[0] = (uint)(mpower[0] - nmana);
            }

            b.Add((byte)powerType).
            Add(mpower[0], mpower[1], mpower[2], mpower[3], mpower[4]).
            Add(power[0], power[1], power[2], power[3], mpower[4]);
            h["Power"] = (byte[])b;
            b.Length   = 0;

            b.Add(mhealth, health);
            h["Health"] = (byte[])b;
            b.Length    = 0;

            mhealth = (uint)(mhealth + nhealth);
            if (powerType == PowerType.MANA)
            {
                mpower[0] = (uint)(mpower[0] + nmana);
            }

            b.Add(attack).Add(minDamage, maxDamage).Add(attackTime0).Add(attackTime1);
            h["Attack"] = (byte[])b;
            b.Length    = 0;

            h["DisplayID"] = (int)displayID;
            h["Level"]     = (int)level;
            h["XP"]        = (int)xp;
            h["RestXP"]    = (int)restxp;
            h["TimeStamp"] = (int)Const.GetTimeStamp();

            h["Items"] = GetItemsSaveData();

            MemoryStream ms = new MemoryStream();

            (new DBSerial(ms)).Serialize(h);
            return(ms.ToArray());
        }
Beispiel #27
0
 public void BuildSpellData(ByteArrayBuilder pack)
 {
     pack.Add((byte)0);
     pack.Add((ushort)0);
 }
Beispiel #28
0
        public void SendUpdate(bool bBuild)
        {
            if (bBuild)
            {
                BuildUpdateForSet();
            }
            if (updatePacket.Count == 0)
            {
                return;
            }

            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add(new byte[5]);

            int cnt = 0;

            foreach (byte[] b in updatePacket)
            {
                pack.Add(b);
                cnt++;
                if (pack.Length > 32000)
                {
                    break;
                }
            }
            updatePacket.RemoveRange(0, cnt);
            pack.Set(0, (ushort)cnt);

            byte[] data = pack;
            if (data.Length > 400)       // need compress?
            {
                /*/ ICSharpCode.SharpZipLib.Zip.Compression.Deflater deflater = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater();
                 *               deflater.SetInput(data);
                 *               deflater.Finish();
                 *
                 *               byte[] cdata = new byte[data.Length];
                 *               int len = deflater.Deflate(cdata);
                 *
                 * Console.WriteLine(len);
                 * Console.WriteLine(data.Length);
                 *               pack.Length = 0;
                 * //    pack = new ByteArrayBuilder(false);
                 * pack.Add((uint)data.Length / 8);
                 * for (int i = 0; i < len; i++)
                 *   pack.Add(cdata[i]);
                 * Console.WriteLine(pack.Length);
                 */

                // Well, it works.... :-)
                byte[] temp = { 163,   4,   0,   0, 120, 156,  99,  99,   0,
                                2,    38,  38,  32, 193,   8, 197, 120, 128, 130,   3,   3, 195,
                                3,     7,  16,  93,  36,  51,  29,  72,
                                55,   56, 220, 225, 247, 116,  96, 192, 162, 145,
                                233, 190,  63, 148,   1, 149, 100,   6,  98,  46, 176,
                                72,  131,  61,  55,  84,  17,  55, 154,  38,
                                144,  58,  38, 102, 154,  57,   5, 102,  50,  51,
                                220, 106,   2,  78,  97, 161, 153,  83,  96,  38, 131,
                                156, 194,  67, 140,  83,  96,  12, 234,  59,   5,  38, 201,
                                12,   87,  68, 192,  41,  48, 103,  80, 223,  41,  48,
                                83,   65,  78,  97,  34, 198,  41,  48,  65,
                                22,  152, 232,   5,   9, 238,  99, 167, 140,  12,  14,
                                31,   82,  95, 236, 116, 212, 203, 213,   1, 159,  83,
                                176, 249,  65,  81, 158, 193,  57,  80, 198,   1,
                                33,  112,  99,  62, 195, 207, 253,  12,  15,  56,  17,  34,  28,  12,  12,  14,
                                13,   48,  78,   3, 216,   4,  30, 126,   6,  27,  20,  99,  14,
                                48,  144,   8,  64,  62, 102, 248,   3, 229, 192, 124,  37,   9, 151, 110, 176,
                                135, 177, 108, 208, 104, 120, 100,   0,   1, 136,
                                159, 195,  14, 193, 198, 198, 198,  64,  61,  11,
                                236, 141, 128,  98,  70,   8, 123,  28,  64, 158, 135, 113, 196, 129,  88,   4,136, 197, 160, 180, 8,
                                204,  33,  88,   0, 114, 240,  51,  50, 176, 179,   2,   9, 102,
                                193, 111,  79, 153, 184, 160, 114,  60,  12, 136,
                                132, 138, 156, 229,  65,  52,  44, 177, 163, 184,
                                23,  202, 127, 129, 100,  97,  10,  14, 187,   1, 224,  91,  68, 126 };
                pack = new ByteArrayBuilder();
                pack.Add(temp);
                Send(OP.SMSG_COMPRESSED_UPDATE_OBJECT, pack);
            }
            else
            {
                Send(OP.SMSG_UPDATE_OBJECT, data);
            }
        }
        public override byte[] OnRecv(byte[] section, int length)
        {
            int t;

            byte[] data;

            for (int i = 0; i < length; i++)
            {
                input.Add(section[i]);
            }
            RealmType code = (RealmType)input[0];

            switch (code)
            {
            case RealmType.LOGON_CHALLENGE:                    //   Logon challenge
            case RealmType.RECONNECT_CHALLENGE:
            {
                if (input.Length < 34 || input.Length < 34 + input[33])
                {
                    return(null);
                }

                int clientVersion = input.Seek(11).GetWord();

                //byte[] blu = input.GetArray(5, input[33]);
                //Console.WriteLine("DEBUG:" + clientVersion);

                userName = input.GetArray(34, input[33]);

                data = input; input.Length = 0;

                sUserName = System.Text.Encoding.ASCII.GetString(userName);
                //string ble = System.Text.Encoding.ASCII.GetString(blu);

                byte [] hash = rl.GetUserPasswordHash(sUserName);
                //Console.WriteLine("DEBUG - ble:" + ble + "user: "******" code: " + code);
                    }

                    ByteArrayBuilder p = new ByteArrayBuilder();
                    p.Add((byte)1, 3);
                    p.Add(new byte[116]);
                    return(p);
                }

                if (LogMessageEvent != null)
                {
                    LogMessageEvent(sUserName + " code: " + code);
                }

                byte [] res = new Byte[hash.Length + salt.Length];
                Const.rand.NextBytes(salt);
#if CHECK
                salt = new byte[] { 0x33, 0xf1, 0x40, 0xd4, 0x6c, 0xb6, 0x6e, 0x63, 0x1f, 0xdb, 0xbb, 0xc9, 0xf0, 0x29, 0xad, 0x88, 0x98, 0xe0, 0x5e, 0xe5, 0x33, 0x87, 0x61, 0x18, 0x18, 0x5e, 0x56, 0xdd, 0xe8, 0x43, 0x67, 0x4f };
#endif

                t = 0;
                foreach (byte s in salt)
                {
                    res[t++] = s;
                }
                foreach (byte s in hash)
                {
                    res[t++] = s;
                }

                SHA1    sha   = new SHA1CryptoServiceProvider();
                byte [] hash2 = sha.ComputeHash(res, 0, res.Length);
                byte [] x     = Reverse(hash2);

                rN = Reverse(N);
                Const.rand.NextBytes(b);
#if CHECK
                b = new byte[] { 0x86, 0x92, 0xE3, 0xA6, 0xBA, 0x48, 0xB5, 0xB1, 0x00, 0x4C, 0xEF, 0x76, 0x82, 0x51, 0x27, 0xB7, 0xEB, 0x7D, 0x1A, 0xEF };
#endif
                rb = Reverse(b);


                BigInteger bi  = new BigInteger(x);
                BigInteger bi2 = new BigInteger(rN);
                G = new BigInteger(new byte[] { 7 });
                v = G.modPow(bi, bi2);

                K = new BigInteger(new Byte[] { 3 });
                BigInteger temp1 = K * v;
                BigInteger temp2 = G.modPow(new BigInteger(rb), new BigInteger(rN));
                BigInteger temp3 = temp1 + temp2;
                B = temp3 % new BigInteger(rN);

                ByteArrayBuilder pack = new ByteArrayBuilder();
                pack.Add((byte)0, 0, 0);
                pack.Add(Reverse(B.getBytes(32)));
                pack.Add((byte)1, 7, 32);
                pack.Add(N);
                pack.Add(salt);
                pack.Add(new byte[16]);
                return(pack);
            }

            case RealmType.LOGON_PROOF:                    //   Logon proof
            case RealmType.RECONNECT_PROOF:
            {
                if (input.Length < 53)
                {
                    return(null);
                }

                byte[] A   = input.GetArray(1, 32);
                byte[] kM1 = input.GetArray(33, 20);

                data         = input;
                input.Length = 0;


#if CHECK
                A = new byte[] { 0x23, 0x2f, 0xb1, 0xb8, 0x85, 0x29, 0x64, 0x3d, 0x95, 0xb8, 0xdc, 0xe7, 0x8f, 0x27, 0x50, 0xc7, 0x5b, 0x2d, 0xf3, 0x7a, 0xcb, 0xa8, 0x73, 0xeb, 0x31, 0x07, 0x38, 0x39, 0xed, 0xa0, 0x73, 0x8d };
#endif

                byte [] rA = Reverse(A);

                byte [] AB = Concat(A, Reverse(B.getBytes(32)));

                SHA1    shaM1 = new SHA1CryptoServiceProvider();
                byte [] U     = shaM1.ComputeHash(AB);

                byte [] rU = Reverse(U);

                // SS_Hash
                BigInteger temp1 = v.modPow(new BigInteger(rU), new BigInteger(rN));
                BigInteger temp2 = temp1 * new BigInteger(rA);
                BigInteger temp3 = temp2.modPow(new BigInteger(rb), new BigInteger(rN));

                byte [] S1 = new byte[16];
                byte [] S2 = new byte[16];
                byte [] S  = temp3.getBytes(32);
                byte [] rS = Reverse(S);

                for (t = 0; t < 16; t++)
                {
                    S1[t] = rS[t * 2];
                    S2[t] = rS[(t * 2) + 1];
                }
                byte [] hashS1  = shaM1.ComputeHash(S1);
                byte [] hashS2  = shaM1.ComputeHash(S2);
                byte [] SS_Hash = new byte[hashS1.Length + hashS2.Length];
                for (t = 0; t < hashS1.Length; t++)
                {
                    SS_Hash[t * 2]       = hashS1[t];
                    SS_Hash[(t * 2) + 1] = hashS2[t];
                }

                // cal M1
                byte [] NHash    = shaM1.ComputeHash(N);
                byte [] GHash    = shaM1.ComputeHash(G.getBytes());
                byte [] userHash = shaM1.ComputeHash(userName);
                byte [] NG_Hash  = new byte[20];
                for (t = 0; t < 20; t++)
                {
                    NG_Hash[t] = (byte)(NHash[t] ^ GHash[t]);
                }
                byte [] Temp = Concat(NG_Hash, userHash);
                Temp = Concat(Temp, salt);
                Temp = Concat(Temp, A);
                Temp = Concat(Temp, Reverse(B.getBytes(32)));
                Temp = Concat(Temp, SS_Hash);

                byte [] M1 = shaM1.ComputeHash(Temp);

                ByteArrayBuilder pack;
                if (!ByteArray.Same(M1, kM1))
                {
                    if (LogMessageEvent != null)
                    {
                        LogMessageEvent(sUserName + " code: " + code);
                    }

                    pack = new ByteArrayBuilder();
                    pack.Add((byte)1, 3);
                    pack.Add(new byte[24]);
                    return(pack);
                }

                if (LogMessageEvent != null)
                {
                    LogMessageEvent(sUserName + " code: " + code);
                }

                rl.SetUserSessionKey(sUserName, SS_Hash);

                // cal M2
                Temp = Concat(A, M1);
                Temp = Concat(Temp, SS_Hash);
                byte [] M2 = shaM1.ComputeHash(Temp);

                pack = new ByteArrayBuilder();
                pack.Add((byte)1, 0);
                pack.Add(M2);
                pack.Add(new byte[4]);

                return(pack);
            }

            case RealmType.UPDATESRV:                     // Update server
                if (input.Length < 1)
                {
                    return(null);
                }
                data = input; input.Length = 0;
                if (LogMessageEvent != null)
                {
                    LogMessageEvent("UPDATESRV");
                }
                break;

            case RealmType.REALMLIST:                     // Realm List
            {
                if (input.Length < 1)
                {
                    return(null);
                }
                byte[] request = input.GetArray(1, 4);
                input.Length = 0;
                if (LogMessageEvent != null)
                {
                    LogMessageEvent("REALMLIST");
                }
                ByteArrayBuilder pack = new ByteArrayBuilder(false);
                pack.Add((byte)RealmType.REALMLIST, 0, 0);
                pack.Add(request);

                rl.GetRealmList(sUserName, pack);

                pack.Add((byte)0, (byte)0);
                pack.Set(1, (ushort)(pack.Length - 3));

                return(pack);
            }

            default:
                data = input; input.Length = 0;
                if (LogMessageEvent != null)
                {
                    LogMessageEvent("Receive unknown command {0}" + data[0]);
                }
                break;
            }
            byte [] ret = { 0, 0 };
            return(ret);
        }
Beispiel #30
0
        /*
         * 3A 09 00 00 04 00 00 00 06 00 00 00 57 6F 72 6E 20 57 6F 6F 64 65 6E 20 53 68 69 65 6C 64 00 00 00 00 2A 49 00 00 00 00 00 00 00 00 00 00 07 00 00 00 01 00 00 00 0E 00 00 00 FF 7F 00 00 FF 01 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 14 00 00 00
         * 3A 09 00 00 04 00 00 00 06 00 00 00 57 6F 72 6E 20 57 6F 6F 64 65 6E 20 53 68 69 65 6C 64 00 00 00 00 2A 49 00 00 00 00 00 00 00 00 00 00 07 00 00 00 01 00 00 00 0E 00 00 00 FF 7F 00 00 FF 01 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 14 00 00 00
         *
         * E8 17 00 00
         * 04 00 00 00
         * 00 00 00 00
         * 52 65 63 72 75 69 74 27 73 20 53 68 69 72 74 00
         * 00
         * 00
         * 00
         *
         * FF 26 00 00
         * 01 00 00 00
         * 00 00 00 00
         * 01 00 00 00 // bprice
         * 01 00 00 00 // sprice
         * 04 00 00 00 // itype
         * FF 7F 00 00 // classes
         * FF 01 00 00 // races
         * 01 00 00 00 // level
         * 00 00 00 00 // reqlevel
         * 00 00 00 00 // skill
         * 00 00 00 00 // skillrank
         * 00 00 00 00 // 2
         * 00 00 00 00 // 3
         * 00 00 00 00 // 4
         * 00 00 00 00 // maxcou
         * 01 00 00 00 // stackable
         * 00 00 00 00 // containerslots
         *
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         * FF FF FF FF 00 00 00 00
         *
         * 00 00 00 00 00 00 00 00 FF FF FF FF
         * 00 00 00 00 00 00 00 00 FF FF FF FF
         * 00 00 00 00 00 00 00 00 FF FF FF FF
         * 00 00 00 00 00 00 00 00 FF FF FF FF
         * 00 00 00 00 00 00 00 00 FF FF FF FF
         *
         *                                                                                                                                                                                                                                                                                                                                                      00 00 00 00
         * 00 00 00 00 00 00 00 00
         * 00 00 00 00 00 00 00 00
         * 00 00 00 00 00 00 00 00
         * 00 00 00 00 00 00 00 00
         * 00 00 00 00
         *
         *
         * FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         * FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         * FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         * FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         * FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         *
         * 00 00 00 00 // bonding
         * 00          // desc
         * 00 00 00 00 // Pagetext
         * 00 00 00 00 // LanguageID
         * 00 00 00 00 // PageMaterial
         * 00 00 00 00 // StartQuestID
         * 00 00 00 00 // LockID
         * 07 00 00 00 // material
         * 00 00 00 00 // Sheathetype
         * 00 00 00 00 // Unknown1
         * 00 00 00 00 // block
         * 00 00 00 00 // Unknown3
         * 00 00 00 00 // durability
         */

        void QuerySingle(OP code, PlayerConnection c)
        {
            uint  entry;
            ulong guid;

            c.Seek(2).Get(out entry).Get(out guid);

            Item      n    = new Item(gameServer);
            Hashtable data = n.GetData(entry);

            if (data == null)
            {
                gameServer.LogMessage("code not found! -> QuerySingle code: " + code + " entry: " + entry + "  guid:" + guid);
                return;
            }

            gameServer.LogMessage("QuerySingle code: " + code + " entry: " + entry + "  guid:" + guid);

            ByteArrayBuilder pack = new ByteArrayBuilder(false);

            pack.Add(entry);
            pack.Add(Get(data, "class", 1));
            pack.Add(Get(data, "subclass", 0));
            pack.Add(data["name"] as string);
            if (data.Contains("questname"))
            {
                pack.Add(data["questname"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            if (data.Contains("name3"))
            {
                pack.Add(data["name3"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            if (data.Contains("name4"))
            {
                pack.Add(data["name4"] as string);
            }
            else
            {
                pack.Add((byte)0);
            }
            pack.Add(Get(data, "model", 0));
            pack.Add(Get(data, "quality", 1));
            pack.Add(Get(data, "flags", 0));
            pack.Add(Get(data, "buyprice", 0));
            pack.Add(Get(data, "sellprice", 0));
            pack.Add(Get(data, "inventorytype", 0));
            pack.Add(Get(data, "classes", 0x7fff));
            pack.Add(Get(data, "races", 0x1ff));
            pack.Add(Get(data, "level", 1));
            pack.Add(Get(data, "reqlevel", 1));
            pack.Add(Get(data, "skill", 0));
            pack.Add(Get(data, "skillrank", 0));
            pack.Add((uint)0, 0, 0);
            pack.Add(Get(data, "maxcount", 0));
            pack.Add(Get(data, "stackable", 1));
            pack.Add(Get(data, "containerslots", 0));

            int[] bonus = data["bonus"] as int[];
            for (int i = 0; i < 10; i++)
            {
                if (bonus != null && i < bonus.Length / 2)
                {
                    pack.Add((uint)bonus[i * 2], (uint)bonus[i * 2 + 1]);
                }
                else
                {
                    pack.Add((uint)0xffffffff, 0);
                }
            }

            int[] damage = data["damage"] as int[];
            for (int i = 0; i < 5; i++)
            {
                if (damage != null && i < damage.Length / 3)
                {
                    pack.Add((float)damage[i * 3], (float)damage[i * 3 + 1], (uint)damage[i * 3 + 2]);
                }
                else
                {
                    pack.Add((uint)0, 0, (uint)0xffffffff);
                }
            }

            pack.Add(Get(data, "resistance1", 0));
            pack.Add(Get(data, "resistance2", 0));
            pack.Add(Get(data, "resistance3", 0));
            pack.Add(Get(data, "resistance4", 0));
            pack.Add(Get(data, "resistance5", 0));
            pack.Add(Get(data, "resistance6", 0));
            pack.Add(Get(data, "resistance7", 0));
            pack.Add(Get(data, "delay", 3000));
            pack.Add((uint)0);

            int[] spell = data["spell"] as int[];
            for (int i = 0; i < 5; i++)
            {
                if (spell != null && i < spell.Length / 6)
                {
                    pack.Add((uint)spell[i * 6],
                             (uint)spell[i * 6 + 1],
                             (uint)spell[i * 6 + 2],
                             (uint)spell[i * 6 + 3],
                             (uint)spell[i * 6 + 4],
                             (uint)spell[i * 6 + 5]);
                }
                else
                {
                    pack.Add((uint)0xffffffff, 0, 0, 0, 0, 0);
                }
            }

            pack.Add(Get(data, "bonding", 0));
            pack.Add((byte)0);
            pack.Add(Get(data, "pagetext", 0));
            pack.Add(Get(data, "language", 0));
            pack.Add(Get(data, "pagematerial", 0));
            pack.Add(Get(data, "startquest", 0));
            pack.Add(Get(data, "lockid", 0));
            pack.Add(Get(data, "material", 0));
            pack.Add(Get(data, "sheath", 0));
            pack.Add(Get(data, "ukn1", 0));
            pack.Add(Get(data, "block", 0));
            pack.Add(Get(data, "ukn3", 0));
            pack.Add(Get(data, "durability", 0));

            c.Send(OP.SMSG_ITEM_QUERY_SINGLE_RESPONSE, pack);
        }