public static void SendResponseLoadCharacters(ClientManager MyClient)
        {
            //Console.WriteLine("Sending characters info to: " + MyClient.data.username + ", " + MyClient.data.id_idx);

            // get characters count

            int CharactersCount = Database.gamedata.GetCharactersCount(MyClient.data.id_idx);
            //Console.WriteLine("Characters count: " + CharactersCount);
            List <XHERO> Heroes = Database.gamedata.GetAllHeroesFromID(MyClient.data.id_idx);


            using (MemoryStream ms = new MemoryStream())
            {
                int len = 0;
                using (BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8))
                {
                    bw.Write((byte)0x02);            // write packet type
                    //bw.Write((byte)0x00); // ATT NEW CLIENT
                    bw.Write((byte)CharactersCount); // write characters count
                    if (CharactersCount > 0)
                    {
                        for (int i = 0; i < Heroes.Count; i++)
                        {
                            /*
                             * Console.WriteLine("[" + i + "] Hero_oder: " + Heroes[i].hero_order);
                             * Console.WriteLine("[" + i + "] Name: " + Heroes[i].name);
                             * Console.WriteLine("[" + i + "] Hero_type: " + Heroes[i].hero_type);
                             * Console.WriteLine("[" + i + "] Hero_LV: " + Heroes[i].baselevel);
                             * Console.WriteLine("[" + i + "] Avatar_head: " + Heroes[i].avatar_head); */
                            bw.Write((byte)Heroes[i].hero_order);
                            foreach (char c in Heroes[i].name)
                            {
                                bw.Write((byte)c);
                            }
                            bw.Write((byte)0x00);
                            bw.Write((byte)Heroes[i].hero_type);
                            bw.Write((short)Heroes[i].baselevel);
                            bw.Write((short)Heroes[i].avatar_head);
                            bw.Write((short)190); // weapown equiped
                            bw.Write((short)98);  // armour equiped
                            if (Heroes[i].status == 1)
                            {
                                bw.Write((byte)0x01);
                                bw.Write((int)Heroes[i].status_time);
                            }
                            else
                            {
                                bw.Write((byte)0x00);
                                bw.Write((int)604800); // unknow
                            }


                            List <XMOB> HeroMobs = Database.gamedata.GetAllMobsEquipedFromID(MyClient.data.id_idx, Heroes[i].hero_order);
                            if (HeroMobs.Count > 0)
                            {
                                bw.Write((byte)HeroMobs.Count);
                                for (int j = 0; j < HeroMobs.Count; j++)
                                {
                                    bw.Write((byte)j);
                                    bw.Write((short)HeroMobs[j].monster_type);
                                }
                            }
                            else
                            {
                                bw.Write((byte)0x00);
                            }
                        }

                        len = (int)bw.BaseStream.Length;
                    }
                    byte[] buffer = ms.GetBuffer();
                    Array.Resize(ref buffer, len);
                    MakePacketAndSend(MyClient, buffer);
                }
            }
        }
        public static void ParsePacket(ClientManager MyClient, byte[] data)
        {
            if (MyClient == null)
            {
                return;
            }
            if (MyClient._socket == null)
            {
                return;
            }
            if (!MyClient._socket.Connected)
            {
                return;
            }

            byte[] PacketDecrypted = PacketFunctions.GetPacketDataDecrypted(data);

            using (MemoryStream ms = new MemoryStream(PacketDecrypted))
            {
                using (BinaryReader br = new BinaryReader(ms))
                {
                    int id_idx = br.ReadInt32();
                    if (!ClientFunctions.SearchUserIDInSession(id_idx))
                    {
                        Console.WriteLine("Client not found in list");
                        return;
                    }


                    br.ReadByte();
                    byte PacketType = br.ReadByte();

                    if (MyClient.data.Authenticated)
                    {
                        switch (PacketType)
                        {
                        case 2:     // load characters data
                            //Console.WriteLine("Receive load character!");
                            SendData.SendResponseLoadCharacters(MyClient);
                            SendData.SendResponseGMSInfo(MyClient);
                            return;

                            break;

                        case 3:     // send create character prev data
                            //Console.WriteLine("Receive get create char data!");
                            SendData.SendResponseCreateCharData(MyClient);
                            return;

                            break;

                        case 4:     // delete character
                            //Console.WriteLine("Receive delete hero request!");
                            ProcessDeleteHeroReceive(MyClient, PacketDecrypted);
                            return;

                            break;

                        case 5:     // create hero
                            //Console.WriteLine("Receive create hero!");
                            ProcessCreateHeroReceive(MyClient, PacketDecrypted);
                            return;

                            break;

                        case 6:     // select hero
                            Console.WriteLine("[HeroSelect] Request hero select.");
                            ProcessHeroSelected(MyClient, PacketDecrypted);
                            break;

                        case 10:     // guild mark list
                            break;

                        case 32:     // change heroname
                            break;
                        }
                    }

                    float exe_version = br.ReadSingle();
                    if (exe_version != MyInfo.EXE_VERSION)
                    {
                        //Console.WriteLine("Client use exe_version old version");
                        // disconnect by using client old_version
                        return;
                    }

                    int    id_idx2        = br.ReadInt32();
                    int    LGS_TOKEN      = br.ReadInt32();
                    byte[] username_bytes = br.ReadBytes(32);
                    string username       = PacketFunctions.ExtractStringFromBytes(username_bytes);

                    if (!ClientFunctions.TokenIsValidInSession(id_idx2, LGS_TOKEN, username))
                    {
                        //Console.WriteLine("Incorrect token!");
                        // disconnect by using a incorrect token
                        return;
                    }

                    MyClient.data.id_idx        = id_idx2;  // copy id_idx valid from packet
                    MyClient.data.username      = username; // copy username valid from packet
                    MyClient.data.Authenticated = true;     // confirm client authenticated aprove
                    SendData.SendAprovedAuthentication(MyClient);
                    SendData.SendAprovedSession(MyClient);
                    //Console.WriteLine("[W] User auth aproved! " + username + ":" + id_idx2);
                }
            }
        }
 public static void SendAprovedSession(ClientManager MyClient)
 {
     Send(MyClient, new byte[] { 0x02, 0x00, 0x09, 0xa8, 0xc5 });
 }
        private static void ReceiveCallback(IAsyncResult ar)
        {
            byte[]        Data;
            ClientManager MyClient = (ClientManager)ar.AsyncState;
            Socket        client   = MyClient._socket;


            if (client == null)
            {
                return;
            }
            if (!client.Connected)
            {
                return;
            }
            int BufferSize = getPendingByteCount(client);

            if (BufferSize > 1000)
            {
                return;
            }

            try
            {
                int BytesReceive = client.EndReceive(ar);
                if (BytesReceive > 0)
                {
                    Data = new byte[BytesReceive];
                    Array.Copy(MyClient.buffer, Data, BytesReceive);
                    ReceiveData.ParsePacket(MyClient, Data);
                    MyClient.buffer = new byte[ClientManager.BufferSize];

                    // Process received data
                }
                else
                {
                    ClientFunctions.DisconnectClientFromID(MyClient.id);
                    ClientFunctions.RemoveClientFromInstance(MyClient);
                }
                client.BeginReceive(MyClient.buffer, 0, ClientManager.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), MyClient);
            }
            catch (SocketException e)
            {
                if (e.ErrorCode == 10054)
                {
                    ClientFunctions.DisconnectClientFromID(MyClient.id);
                    ClientFunctions.RemoveClientFromInstance(MyClient);
                    //Console.WriteLine("Client disconnected!");
                    return;
                }
            }
            catch
            {
                ClientFunctions.DisconnectClientFromID(MyClient.id);
                ClientFunctions.RemoveClientFromInstance(MyClient);
                //Console.WriteLine("Client disconnected!");
                // add to log receive error
                // remove client connected if is a error: remove from clients list
                //
                return;
            }
        }