예제 #1
0
        public static void QuestNextStep(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var questid  = packet.ReadUShort();
            var questid1 = packet.ReadUShort();

            packet.Skip(3);
            var previousstep = packet.ReadByte();
            var nextstep     = packet.ReadByte();

            /*
             * builder.New(0x0140);
             * {
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             *  builder += (byte)1;
             * }*/

            builder.New(0x0140);
            {
                builder += questid;
                builder += (ushort)(previousstep + nextstep);
                builder += questid1;
                builder += (ushort)0;
            }

            client.Send(builder, "QuestNextStep");
        }
예제 #2
0
        public static void ArrivedAtLocation(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var x = packet.ReadUShort();
            var y = packet.ReadUShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;

            character.x = (byte)x;
            character.y = (byte)y;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            (client.Metadata["map"] as IMap).GetTile(client, x, y);

            builder.New(0xD3);
            {
                builder += id;
                builder += x;
                builder += y;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_MoveEnded");
            }
        }
예제 #3
0
        public static void ArrivedAtLocation(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var x = packet.ReadUShort();
            var y = packet.ReadUShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;

            character.x = (byte)x;
            character.y = (byte)y;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            (client.Metadata["map"] as IMap).GetTile(client, x, y);

            builder.New(0xD3);
            {
                builder += id;
                builder += x;
                builder += y;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_MoveEnded");
            }

            NewMobsList(packet, builder, client, events);
            //NewUserList(packet, builder, client, events);

            CharacterManagement.UpdatePosition(client.Metadata["syncServer"] as SyncReceiver, (int)client.Metadata["server"], client.AccountID, character.slot, character.map, character.x, character.y);
        }
예제 #4
0
        public static void RecvCashItem(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            builder.New(0x1A3);
            {
                var ID       = packet.ReadUShort();
                var unk1     = packet.ReadByte();
                var unk2     = packet.ReadByte();
                var SlotFree = packet.ReadByte();
                var unk4     = packet.ReadByte();



                Character character  = client.Metadata["fullchar"] as Character;
                var       cid        = character.id;
                var       server     = (int)client.Metadata["server"];
                var       syncServer = client.Metadata["syncServer"] as SyncReceiver;
                var       slot       = character.slot;

                var CashItens = CharacterManagement.GetCashItem(syncServer, server, cid / 8);

                for (int i = 0; i < CashItens.Length; i++)
                {
                    if (CashItens[i].ID == ID)
                    {
                        builder += (int)ID;
                        builder += (int)CashItens[i].itemid;
                        builder += CashItens[i].itemopt;
                        builder += (int)CashItens[i].itemopt2;
                        builder += (int)SlotFree;
                        builder += (int)0;
                        builder += (short)0;

                        CharacterManagement.SetCashItem(syncServer, server, CashItens[i].ID);
                    }
                }

                //Log.Message(string.Format("'{0}' '{1}' '{2}' '{3}' '{4}'", ID, unk1, unk2, SlotFree, unk4), ConsoleColor.White, "Recv: ");

                /*
                 * builder += (int)unk0;       //item cashid
                 * builder += (int)163865;         //item idx
                 * builder += (int)244;          //item opt extreme
                 * builder += (int)536871167;  //item opt old
                 * builder += (int)0;          //item opt
                 * builder += (byte)unk3;      //Slot Free
                 * builder += (byte)0;
                 * builder += (byte)0;
                 * builder += (byte)0;
                 *
                 * builder += (int)0;
                 * builder += (short)0;*/
            }

            client.Send(builder, "RecvCashItem");
        }
예제 #5
0
        public static void AlterDestination(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var turnX = packet.ReadUShort();
            var turnY = packet.ReadUShort();
            var endX  = packet.ReadUShort();
            var endY  = packet.ReadUShort();
            //var unkX = packet.ReadShort();
            //var unkY = packet.ReadShort();
            //var unk0 = packet.ReadShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;
            var       timestamp = (uint)client.Metadata["timestamp"];

            character.x = (byte)turnX;
            character.y = (byte)turnY;
            client.Metadata["dest_x"] = endX;
            client.Metadata["dest_y"] = endY;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            builder.New(0xD4);
            {
                builder += id;
                builder += Environment.TickCount - timestamp;
                builder += turnX;
                builder += turnY;
                builder += endX;
                builder += endY;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_MoveChanged");
            }

            NewMobsList(packet, builder, client, events);
            //NewUserList(packet, builder, client, events);

            CharacterManagement.UpdatePosition(client.Metadata["syncServer"] as SyncReceiver, (int)client.Metadata["server"], client.AccountID, character.slot, character.map, character.x, character.y);
        }
예제 #6
0
        public static void ChangeDirection(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var x = packet.ReadUShort();
            var y = packet.ReadUShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            builder.New(0x188);
            {
                builder += id;
                builder += x;
                builder += y;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_ChangeDirection");
            }
        }
예제 #7
0
        public static void MoveToLocation(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var startX = packet.ReadUShort();
            var startY = packet.ReadUShort();
            var endX   = packet.ReadUShort();
            var endY   = packet.ReadUShort();
            //var unkX = packet.ReadShort();
            //var unkY = packet.ReadShort();
            //var map = packet.ReadShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;
            var       timestamp = (uint)client.Metadata["timestamp"];

            character.x = (byte)startX;
            character.y = (byte)startY;
            client.Metadata["dest_x"] = endX;
            client.Metadata["dest_y"] = endY;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            builder.New(0xD2);
            {
                builder += id;
                builder += Environment.TickCount - (int)timestamp;
                builder += startX;
                builder += startY;
                builder += endX;
                builder += endY;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_MoveBegined");
            }
            //NewUserList(packet, builder, client, events);
            NewMobsList(packet, builder, client, events);
        }
예제 #8
0
        public static void AlterDestination(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var turnX = packet.ReadUShort();
            var turnY = packet.ReadUShort();
            var endX  = packet.ReadUShort();
            var endY  = packet.ReadUShort();
            //var unkX = packet.ReadShort();
            //var unkY = packet.ReadShort();
            //var unk0 = packet.ReadShort();

            Character character = client.Metadata["fullchar"] as Character;
            var       id        = character.id;
            var       timestamp = (uint)client.Metadata["timestamp"];

            character.x = (byte)turnX;
            character.y = (byte)turnY;
            client.Metadata["dest_x"] = endX;
            client.Metadata["dest_y"] = endY;

            var clients = (client.Metadata["map"] as IMap).GetSurroundingClients(client, 2);

            builder.New(0xD4);
            {
                builder += id;
                builder += Environment.TickCount - timestamp;
                builder += turnX;
                builder += turnY;
                builder += endX;
                builder += endY;
            }

            foreach (var c in clients)
            {
                c.Send(builder, "NFY_MoveChanged");
            }
        }
예제 #9
0
        public static void AddSkillPoints(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var       sync      = client.Metadata["syncServer"] as SyncReceiver;
            var       server    = (int)client.Metadata["server"];
            Character character = client.Metadata["fullchar"] as Character;

            var skill    = packet.ReadUShort();
            var slot     = packet.ReadByte();
            var oldlevel = packet.ReadUShort();
            var newlevel = packet.ReadUShort();

            if ((newlevel == oldlevel + 1) || (newlevel == oldlevel - 1))
            {
                CharacterManagement.UpdateSkillPoints(sync, server, character.id, skill, newlevel, slot);
                builder.New(0x0A56);
                client.Send(builder, "AddSkillPoints");
            }
            else //Punishment for hackers :D
            {
                var map = client.Metadata["map"] as IMap;
                CharacterManagement.UpdatePosition(sync, server, client.AccountID, character.slot, character.map, character.x, character.y);
                client.Disconnect();
            }
        }
예제 #10
0
        public static void SkillToMobs(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var skillid = packet.ReadUShort();
            var unk     = packet.ReadInt();
            var unk2    = packet.ReadByte();
            var mobid   = packet.ReadUShort();
            var unk3    = packet.ReadShort();
            var unk4    = packet.ReadByte();
            var dmg     = packet.ReadUInt();
            var unk5    = packet.ReadByte();
            var unk6    = packet.ReadShort();
            var unk7    = packet.ReadShort();
            var unk8    = packet.ReadShort();
            var unk9    = packet.ReadShort();
            var unk10   = packet.ReadShort();
            var unk11   = packet.ReadByte();
            var unk12   = packet.ReadShort();
            var unk13   = packet.ReadShort();

#if DEBUG
            Log.Notice("" + skillid + " " + unk + " " + unk2 + " " + mobid + " " + unk3 + " " + unk4 + " " + dmg + " " + unk5 + " " + unk6 + " " + unk7 + " " + unk8 + " " + unk9 + " " + unk10 + " " + unk11 + " " + unk12 + " " + unk13 + "");
#endif

            //packet.Skip(6);
            var attack = packet.ReadUShort();

            Character character = client.Metadata["fullchar"] as Character;
            uint      hp        = character.stats.curhp;
            uint      mp        = character.stats.curmp;

            character.stats.exp += 100;
            var exp = character.stats.exp;

            /*
             * builder.New(0x00AE);
             * {
             *  builder += skillid;
             *  builder += (byte)1;
             *  builder += (uint)hp;
             *  builder += (uint)mp;
             *  builder += (ushort)0;
             *  builder += (ushort)1;
             *  builder += (uint)2;
             *  builder += (ushort)3;
             *  builder += (uint)4;
             *  builder += (ushort)5;
             *  builder += (uint)6;
             *  builder += (uint)7;
             *  builder += (uint)8;
             *  builder += (uint)9;
             *  builder += (uint)10;
             *  builder += (uint)11;
             *  builder += (uint)12;
             *  builder += (uint)0xFFFFFFFF;
             *  builder += (byte)1;
             *  builder += (uint)13;
             *  builder += (uint)14;
             *  builder += (byte)1;
             *  builder += (ushort)15;
             *  builder += (ushort)16;
             *  builder += (ushort)17;
             *  builder += (uint)18;
             *  builder += (uint)19;
             *  builder += (uint)20;
             *  builder += (uint)21;
             *  builder += (uint)22;
             *  builder += (byte)1;
             * }*/

            builder.New(0x00AE);
            {
                builder += (ushort)skillid;     //skillid
                builder += hp;                  //Hp
                builder += mp;                  //Mp
                builder += (ushort)0;           //Unk
                builder += (ulong)exp;          //Exp
                builder += (int)0xFFFFFFF;      //Skill Exp
                builder += (ushort)0;           //AP
                builder += (uint)0;             //AXP
                builder += (ulong)0;            //Unk1
                builder += (ulong)0;            //Unk2
                builder += (ulong)0;            //Unk3
                builder += (uint)0xFFFFFFFF;
                builder += (byte)1;
                builder += hp;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)1;
                builder += (byte)27;
                builder += (byte)0;
                builder += (byte)1;
                builder += (byte)2;
                builder += (byte)2;
                builder += (byte)2;
                builder += (byte)1;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)0;
                builder += (byte)1;
            }

            client.Send(builder, "SkillToMobs");
        }
예제 #11
0
        public static void NormalAttack(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var MobId = packet.ReadUShort();
            var unk1  = packet.ReadByte();
            var unk2  = packet.ReadByte();
            var unk3  = packet.ReadByte();
            var unk4  = packet.ReadByte();

            Character character  = client.Metadata["fullchar"] as Character;
            var       cid        = character.id;
            var       server     = (int)client.Metadata["server"];
            var       syncServer = client.Metadata["syncServer"] as SyncReceiver;
            var       slot       = character.slot;

#if DEBUG
            Log.Message(string.Format("'{0}' '{1}' '{2}' '{3}' '{4}'", MobId, unk1, unk2, unk3, unk4), ConsoleColor.White, "Sent: ");
#endif

            uint lvl = character.level;
            uint atk = (lvl * character.stats.str_stat) - 17;   //Attempt dmg formula

            ushort maxhp = character.stats.maxhp;
            ushort maxmp = character.stats.maxhp;

            ushort curhp = character.stats.curhp;
            ushort curmp = character.stats.curmp;
            var    map   = client.Metadata["map"] as IMap;

            builder.New(0x00B0);
            {
                builder += MobId;
                builder += unk1;
                builder += unk2;
                builder += unk3;
                builder += (uint)curhp;
                builder += (uint)curmp;
                builder += (ushort)0;
                builder += (byte)0;     //Critical = 1
                builder += (ulong)0;
                builder += (uint)100;
                builder += (uint)0;     //Current Mob Life
                builder += (ushort)0;   //AP
                builder += (uint)0;     //AXP
                builder += (byte)1;     //Display dmg if value >= 1
                builder += (uint)curhp; //Hp hover (where 0/20 sp is displayed)
                builder += (uint)0;     //Dmg Reflected??
            }

            if (curhp > 0)
            {
                character.stats.curhp = curhp;
                character.stats.curmp = curmp;
            }
            else
            {
                character.stats.curhp = maxhp;
                character.stats.curmp = maxmp;

                var p = client.CreatePacket("ErrorCode", packet.Opcode, (ushort)0, (ushort)15, (ushort)map.ID);
                client.Send(p, "ErrorCode");

                builder.New(0x042B);
                {
                    builder += 0;
                    builder += 0;
                    builder += 0;
                }

                client.Send(builder, "unk2");
            }

#if DEBUG
            string notice = "";
            for (int i = 0; i < builder.Size; i++)
            {
                notice += builder.Data[i] + " ";
            }

            Log.Notice(notice);
#endif

            client.Send(builder, "NormalAttack");
        }
예제 #12
0
        public static void WarpCommand(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {

            Character character = client.Metadata["fullchar"] as Character;
            var npc = packet.ReadUShort();
            var unk1 = packet.ReadUShort();
            var unk2 = packet.ReadByte();
            var unk3 = packet.ReadByte();
            var unk4 = packet.ReadByte();

            var y = packet.ReadByte();
            var x = packet.ReadByte();
            var unk5 = packet.ReadByte();
            var unk6 = packet.ReadByte();

            var warpID = packet.ReadUInt();

            var unk7 = packet.ReadByte();
            var unk8 = packet.ReadByte();
            var unk9 = packet.ReadByte();
            var unk10 = packet.ReadByte();
            var unk11 = packet.ReadByte();
            var unk12 = packet.ReadByte();
            var unk13 = packet.ReadByte();
            var unk14 = packet.ReadByte();

            var map = (client.Metadata["map"] as IMap);
            var fee = character.stats.alz;
            var alive = (warpID == 0 && npc != 54 && npc != 63);

            int[] dest = null;

            if (alive)
                dest = map.GetWarpDestination(npc, 0);
            else if (npc == 201)
                warpID = (uint)map.ID;
            else
                dest = map.GetDeathDestination();

            if (dest!=null)
            {
                warpID = (byte)dest[0];
                x = (byte)dest[1];
                y = (byte)dest[2];
            }

            map.GetSurroundingClients(client, 1);
            map.RemoveClient(client);
            events.Warped("world.WarpCommand", client, (int)warpID, x, y);

            builder.New(0x00F4); // TODO: Load x,y values from WarpList
            {
                builder += (ushort)x;
                builder += (ushort)y;
                builder += (uint)character.stats.exp;
                builder += 0;                           //axp
                builder += fee;                         //Alz (for death penalty and fee?)
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (ulong)0;
                builder += warpID;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
                builder += (byte)1;
            }

            #region PacketAnalisys  
#if DEBUG
            string notice = "";

            /*for (int i = 0; i< packet.Size-10; i++)
            {
                notice += packet.ReadByte()+" ";   
            }
            */

            notice += npc + " " + unk1 + " " + unk2 + " " + unk3 + " " + unk4 + " " + x + " " + y + " " + unk5 + " " + unk6 + " " + warpID + " "
                + unk7 + " " + unk8 + " " + unk9 + " " + unk10 + " " + unk11 + " " + unk12 + " " + unk13 + " " + unk14;
            Log.Notice(notice);
#endif
            #endregion

            client.Send(builder, "WarpCommand");

            character.map = (byte)warpID;
            character.x = x;
            character.y = y;

            CharacterManagement.UpdatePosition(client.Metadata["syncServer"] as SyncReceiver, (int)client.Metadata["server"], client.AccountID, character.slot, (byte)warpID, character.x, character.y);
        }
예제 #13
0
        public static void SkillToMobs(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var map     = client.Metadata["map"] as IMap;
            var mapmobs = (client.Metadata["map"] as IMap).GetSurroundingMobs(client, 3);
            var mobdata = map.GetMobsData;



            var skillid = packet.ReadUShort();
            var unk     = packet.ReadInt();
            var unk1    = packet.ReadByte();
            var unk2    = packet.ReadUShort();
            var unk3    = packet.ReadShort();
            var unk4    = packet.ReadByte();
            var dmg     = packet.ReadUInt();
            var unk5    = packet.ReadByte();
            var unk6    = packet.ReadShort();
            var unk7    = packet.ReadShort();
            var unk8    = packet.ReadShort();
            var unk9    = packet.ReadShort();
            var mobid   = packet.ReadShort();
            var unk11   = packet.ReadByte();
            var unk12   = packet.ReadShort();
            var unk13   = packet.ReadShort();

#if DEBUG
            Log.Notice("SkillID:" + skillid + " SkillSlot:" + unk + " unk1:" + unk1 + " unk2:" + unk2 + " unk3:" + unk3 + " unk4:" + unk4 + " dmg:" + dmg + " unk5:" + unk5 + " unk6:" + unk6 + " unk7:" + unk7 + " unk8:" + unk8 + " unk9:" + unk9 + " MobID:" + mobid + " unk11:" + unk11 + " unk12:" + unk12 + " unk13:" + unk13 + "");
#endif

            //packet.Skip(6);
            var attack = packet.ReadUShort();

            Character character = client.Metadata["fullchar"] as Character;
            uint      hp        = character.stats.curhp;
            uint      mp        = character.stats.curmp;

            SkillLoader s         = new SkillLoader();
            var         skilllist = s.LoadSkillData(skillid);
            var         sid       = skilllist.Find(x => x.ID == skillid);

            var char_atk = (int)client.Metadata["patk"];

            if (sid.Type == 1)
            {
                char_atk = (int)client.Metadata["patk"];
            }
            if (sid.Type == 2)
            {
                char_atk = (int)client.Metadata["matk"];
            }

            var mi = mapmobs.Find(x => x.Id == mobid);
            var md = mobdata[mi.SId];

            uint attack_rate = Convert.ToUInt32(new Random().Next(1, 10));

            var normal_atk = char_atk + (sid.Attack + ((sid.Amp / 100) * sid.Attack));

            var mobdef = new Random().Next(md.Defense, md.DefRate);

            var normal_damage = normal_atk - mobdef;
            var crit_damage   = normal_damage + (normal_damage * sid.Critical);

            var damage = 0;

            var atack_result = 0;

            if (attack_rate <= 5)
            {
                atack_result        = 2;
                damage              = normal_damage;
                character.stats.exp = character.stats.exp + (ulong)damage * 2;
            }
            if (attack_rate == 6)
            {
                atack_result        = 1;
                damage              = crit_damage;
                character.stats.exp = character.stats.exp + (ulong)damage * 2;
            }
            if (attack_rate == 7)
            {
                atack_result = 27;
            }

            if (attack_rate >= 8)
            {
                atack_result = 21;
            }

            //Damage Maked
            if (damage < md.Defense && damage > 0)
            {
                damage = new Random().Next(1, 5);
            }

            if (damage >= mi.CurrentHP && damage > 0)
            {
                damage       = mi.CurrentHP;
                mi.CurrentHP = 0;
                //map.DropItem(mi.CurrentPosX, mi.CurrentPosX, 13, 1,1);
            }
            else
            {
                mi.CurrentHP = mi.CurrentHP - damage;
            }


            var exp      = character.stats.exp;
            var skillexp = character.stats.swordrank + sid.Attack;


            builder.New(0x00AE);
            {
                builder += (ushort)skillid;     //skillid
                builder += hp;                  //Hp
                builder += mp;                  //Mp
                builder += (ushort)0;           //SP
                builder += (ulong)exp;          //Exp
                builder += (ulong)0;            //OXP
                builder += (ulong)skillexp;     //SkillEXP

                builder += new byte[26];

                builder += (uint)0xFFFFFFFF;
                builder += (byte)0;
                builder += hp;
                builder += (uint)0;

                builder += (byte)1;

                builder += (byte)mobid;

                builder += (byte)0;

                builder += (byte)map.ID;
                builder += (byte)2;
                builder += (byte)2;

                builder += (byte)atack_result;

                builder += (int)damage;

                builder += (int)mi.CurrentHP;

                builder += new byte[12];
                builder += (byte)1;
            }

            client.Send(builder, "SkillToMobs");

            if (mi.CurrentHP == 0)
            {
                mi.Spawn = Environment.TickCount + md.Respawn * 10;

                mapmobs.Remove(mi);
            }
        }
예제 #14
0
        /*
         * CSC_ATTCKTOMOBS Packet
         * -------------------------
         * Client2Server Structure:
         *
         * ushort  : magic code
         * ushort  : size
         * int     : padding
         * ushort  : opcode
         *
         * ushort  : MobID
         * byte    : MapID
         * byte    : Unkn1             #so far its value as been 2
         * byte    : Unkn2             #so far its value as been 2 as well, so it could be just a short (512)
         * byte    : Unkn3             #so far its value as been 0
         * -------------------------
         * Server2Client Structure:
         *
         * ushort  : magic code
         * ushort  : size
         * ushort  : opcode
         *
         * ushort  : MobID
         * byte    : Unkn1
         * byte    : MapID
         * byte    : Unkn2
         * uint    : CurHp             #Current HP/Life character has.
         * uint    : CurMp             #Current MP/Mana character has.
         * byte[2] : Unkn4             #so far its value as been 00 00
         * byte    : AtkResult         #Enum AttackResult -> Critical = 1; Normal = 2; Block = 1B; Miss = 15;
         * byte    : HitCounter        #Counts number of attacks made to mob
         * byte    : Unkn5             #Usually value between 1 and 3
         * byte[6] : Unkn6             #00
         * uint    : Dmg               #Damage inflicted on mob, Miss = 0; Dmg = Attack - Mob Defense; if(dmg<=0 && !Miss) dmg = 1;
         * uint    : MobHp             #MobHp -= Dmg
         * ushort  : AP
         * uint    : AXP
         * byte    : TakeDmg           #Hp Cost/Hp Sacrifice; Boolean;
         * uint    : HpHover           #Hp where 0/20 sp is displayed if TakeDmg = 1.
         * uint    : DmgTaken          #Amount of dmg recieved/hp sacrificed if TakeDmg = 1.
         * -------------------------
         * Server sends Notify packet OpCode 0x00E1;
         */

        public static void NormalAttack(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events)
        {
            var map     = client.Metadata["map"] as IMap;
            var mapmobs = (client.Metadata["map"] as IMap).GetSurroundingMobs(client, 3);
            var mobdata = map.GetMobsData;

            var MobID = packet.ReadUShort();
            var unk1  = packet.ReadByte();
            var MapID = packet.ReadByte();
            var unk2  = packet.ReadUShort();

            Character character  = client.Metadata["fullchar"] as Character;
            var       cid        = character.id;
            var       server     = (int)client.Metadata["server"];
            var       syncServer = client.Metadata["syncServer"] as SyncReceiver;
            var       slot       = character.slot;

#if DEBUG
            Log.Message(string.Format("'{0}' '{1}' '{2}' '{3}'", MobID, unk1, MapID, unk2), ConsoleColor.Red, "PACKET RECV");
#endif

            var mi = mapmobs.Find(x => x.Id == MobID);

            var md = mobdata[mi.SId];


            //uint defense = Convert.ToUInt32(new Random().Next(1, 10));
            uint attack_rate = Convert.ToUInt32(new Random().Next(1, 10));
            //uint atk = character.stats.str_stat*2;   //Attempt dmg formula
            var atk = (int)client.Metadata["patk"];
            //uint dmg = atk - defense;

            var mobdef        = new Random().Next(md.Defense, md.DefRate);
            var normal_damage = atk - mobdef;
            var crit_damage   = normal_damage + (normal_damage * 20 / 100);
            var dmg           = 0;

            var atack_result = 0;

            if (attack_rate > 0)
            {
                if (attack_rate < 7)
                {
                    if (attack_rate <= 5)
                    {
                        atack_result        = 2;
                        dmg                 = normal_damage;
                        character.stats.exp = character.stats.exp + (ulong)dmg * 2;
                    }
                    if (attack_rate == 6)
                    {
                        atack_result        = 1;
                        dmg                 = crit_damage;
                        character.stats.exp = character.stats.exp + (ulong)dmg * 2;
                    }
                }
                if (attack_rate == 7)
                {
                    atack_result = 27;
                    dmg          = 0;
                }
                if (attack_rate >= 8)
                {
                    atack_result = 21;
                    dmg          = 0;
                }
            }

            if (dmg < md.Defense && dmg < 0)
            {
                dmg = new Random().Next(1, atk);
                character.stats.exp = character.stats.exp + 1;
            }
            if (dmg >= mi.CurrentHP)
            {
                dmg          = mi.CurrentHP;
                mi.CurrentHP = 0;
                //map.DropItem(mi.CurrentPosX, mi.CurrentPosX, 13, 1,1);
            }
            else
            {
                mi.CurrentHP = mi.CurrentHP - dmg;
            }

            ushort maxhp = character.stats.maxhp;
            ushort maxmp = character.stats.maxhp;

            ushort curhp = character.stats.curhp;
            ushort curmp = character.stats.curmp;

            builder.New(0x00B0);
            {
                builder += (short)MobID;
                builder += (byte)unk1;
                builder += (byte)MapID;
                builder += (byte)unk2;
                builder += (uint)curhp;
                builder += (uint)curmp;
                builder += new byte[2];               // Unknown4 ( so far always 00 00 )
                builder += (byte)atack_result;        // AttackResult;
                builder += (byte)0x1B;                // HitCounter
                builder += (byte)0x3;                 // Unknown5
                builder += new byte[6];               // Unknown6


                builder += (ulong)0;                    // OXP
                //builder += (uint)0;               // EXP
                builder += (uint)dmg;                   // DMG take on mob
                builder += (ushort)mi.CurrentHP;        // MobHp
                builder += (byte)0;                     // TakeDmg
                builder += (uint)0;                     // HpHover
                builder += (uint)0;                     // DmgTaken
                builder += (uint)curhp;
                builder += (uint)0;
            }



            if (curhp > 0)
            {
                character.stats.curhp = curhp;
                character.stats.curmp = curmp;
            }

            else
            {
                #region Death PacketInfo

                /*
                 * Death PacketInfo
                 * Server sends ErrorCode Msg (15 = Dead Menu where player can ressurect)
                 * Server sends Packet 0x042B
                 */
                #endregion

                character.stats.curhp = maxhp;
                character.stats.curmp = maxmp;

                var p = client.CreatePacket("ErrorCode", packet.Opcode, (ushort)0, (ushort)15, (ushort)map.ID);
                client.Send(p, "ErrorCode");

                builder.New(0x042B);
                {
                    builder += 0;
                    builder += 0;
                    builder += 0;
                }

                client.Send(builder, "unk2");
            }


#if DEBUG
            string notice = "";
            for (int i = 0; i < builder.Size; i++)
            {
                notice += builder.Data[i].ToString("X2") + " ";
            }

            Log.Notice(notice);
#endif

            client.Send(builder, "NormalAttack");

            if (mi.CurrentHP == 0)
            {
                mi.Spawn = Environment.TickCount + md.Respawn * 10;
            }
        }