/// <summary>
 /// AccountServer connection Status Change event method
 /// Will be executed when connection status to AccountServer is changed
 /// </summary>
 /// <param name="sender">EventDrivenTCPClient object</param>
 /// <param name="status">status of TCPClient</param>
 void AS_ConnectionStatusChanged(EventDrivenTCPClient sender, EventDrivenTCPClient.ConnectionStatus status)
 {
     if (status == EventDrivenTCPClient.ConnectionStatus.Connected)
     {
         AS.Send(Packet.ZoneConnectPacket());
         Logger.Write("AccountServer.log", "AccountServer Connected");
         Config.isASConnected = true;
         Config.CONNECTED_SERVER_COUNT++;
     }
     else
     {
         if (Config.isASConnected)
         {
             Logger.Write("AccountServer.log", "AccountServer Disconnected");
         }
         Config.isASConnected = false;
     }
 }
        /// <summary>
        /// Data received will be received
        /// Further sending to appropriate server (AS,ZS,BS) and keep on reading client stream
        /// </summary>
        /// <param name="asyncResult"></param>
        private void OnDataRead(IAsyncResult asyncResult)
        {
            var client = asyncResult.AsyncState as Client;

            try
            {
                if (client == null)
                {
                    return;
                }
                var networkStream = client.NetworkStream;
                var newClientEp   = (IPEndPoint)client.TcpClient.Client.RemoteEndPoint;
                var read          = networkStream.EndRead(asyncResult);
                if (read == 0 || read < 10)
                {
                    lock (clients)
                    {
                        clients.Remove(client);
                        return;
                    }
                }
                var        packet            = client.Buffer;
                PlayerInfo playerInformation = null;
                if (player.ContainsKey(client.UniqID))
                {
                    playerInformation = player[client.UniqID];
                }
                switch (Packet.GetPacketType(packet, read, playerInformation))
                {
                case Config.INVALID:     //For invalid request i.e packet size 0 or <=10
                    lock (clients)
                    {
                        clients.Remove(client);
                        return;
                    }

                case Config.LOGIN_PACKET:     //Login to ZoneAgent
                    var temp = new byte[4];
                    Array.Copy(packet, 4, temp, 0, 4);
                    var clientId = Packet.GetClientId(temp);
                    client.UniqID = clientId;
                    if (player.ContainsKey(clientId))
                    {
                        var playerInfo = player[clientId];
                        playerInfo.Prepared   = true;
                        playerInfo.ZoneStatus = Config.AS_ID;
                        playerInfo.Client     = client;
                        LS.Send(Packet.CreateClientStatusPacket(clientId, playerInfo.Account));
                        //zonelog update
                        _Main.Update_zonelog(playerInfo.Account + "(" + newClientEp.Address.ToString() + ") User Joined");
                        var character = Packet.CreateGetCharacterPacket(clientId, playerInfo.Account, newClientEp.Address.ToString());
                        AS.Send(character);
                    }
                    break;

                case Config.AS_PACKET:     //Sends packet to AccountServer
                    AS.Send(Packet.AddClientID(packet, client.UniqID, read));
                    break;

                case Config.ZS_PACKET:     //Sends packet to ZoneServer
                    ZS.Send(Packet.CheckForMultiplePackets(packet, client.UniqID, read));
                    break;

                case Config.BS_PACKET:     //Sends packet to BattleServer
                    BS.Send(Packet.CheckForMultiplePackets(packet, client.UniqID, read));
                    break;

                case Config.DISCONNECT_PACKET:     //Disconnect Packet
                    if (player.ContainsKey(client.UniqID))
                    {
                        Config.PLAYER_COUNT--;
                        //player count update
                        _Main.Update_Player_Count();
                        var playerinfo = player[client.UniqID];
                        playerinfo.Prepared = false;
                        LS.Send(Packet.SendDCToLS(client.UniqID, playerinfo.Account, Packet.GetTime()));
                        //zonelog update
                        _Main.Update_zonelog("<LC> UID = " + client.UniqID + " " + playerinfo.Account + " User Left");
                        if (playerinfo.ZoneStatus == Config.ZS_ID)
                        {
                            //to disconnect from zoneserver
                            playerinfo.ZoneStatus = -1;
                            ZS.Send(Packet.AddClientID(packet, client.UniqID, read));
                            ZS.Send(Packet.SendDCToASZS(client.UniqID));
                        }
                        else if (playerinfo.ZoneStatus == Config.BS_ID)
                        {
                            //to disconnect from battleserver
                            playerinfo.ZoneStatus = -1;
                            BS.Send(Packet.AddClientID(packet, client.UniqID, read));
                            BS.Send(Packet.SendDCToASZS(client.UniqID));
                        }
                        else
                        {
                            //to disconnect from character selection screen
                            AS.Send(Packet.AddClientID(packet, client.UniqID, read));
                            AS.Send(Packet.SendDCToASZS(client.UniqID));
                        }
                        player.Remove(client.UniqID);
                        lock (clients)
                        {
                            clients.Remove(playerinfo.Client);
                        }
                    }
                    Write(client.TcpClient, Packet.AddClientID(packet, client.UniqID, read));
                    break;

                case Config.PAYMENT_PACKET:
                    Write(client.TcpClient, Packet.PrivateMessage(client.UniqID, Config.PayMsg));
                    break;
                }
                networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, OnDataRead, client);
            }
            catch (Exception onDataRead)
            {
                Logger.Write(Logger.GetLoggerFileName("ZoneAgent"), "OnDataRead : " + onDataRead.ToString());
            }
        }