public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            networkClient.OutLogMessage("Getting a servers list...");

            //Send greeting
            string greeting = Packet.BuildPacket(FromClient.GREETING);
            networkClient.SendData(greeting);

            //Get response
            Packet packet = networkClient.InputQueue.Pop();

            if (packet != null)
            {
                //Get available servers
                List<string> servers = packet.GetValues("S/@host");

                //Log message
                StringBuilder sServers = new StringBuilder();

                //Store available servers
                foreach (string server in servers)
                {
                    sServers.AppendFormat("{0}{1}", sServers.Length > 0 ? ", " : "", server);
                    client.AdditionalData.Add(ObjectPropertyName.GAME_SERVER, server);
                }

                networkClient.OutLogMessage(sServers.Insert(0, "Available servers: ").ToString());
                return true;
            }

            networkClient.ThrowError("Failed to getting a servers list or the connection was terminated");
            return false;
        }
        public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            bool chatStarted = false;
            networkClient.OutLogMessage("Starting chat...");

            //Get chat info
            string getInfo = Packet.BuildPacket(FromClient.CHAT_CTRL, Chat.START);
            networkClient.SendData(getInfo);

            //Start chat
            Packet chat = networkClient.InputQueue.Pop(FromServer.CHAT_CTRL);
            if (chat != null)
            {
                string chatServer = chat["@server"];
                string sessionId = (string)client.AdditionalData[ObjectPropertyName.SESSION_ID][0];
                chatStarted = networkClient.StartChat(chatServer, sessionId);
                if (chatStarted)
                {
                    //1: Session ID, 2: Login
                    string chatAuth = Packet.BuildPacket(FromClient.CHAT_CTRL, Chat.AUTH,
                        sessionId, client.Login);
                    networkClient.SendChatData(chatAuth);
                }
            }

            networkClient.OutLogMessage(!chatStarted
                ? "WARNING: chat wasn`t started"
                : "Chat was successfully started");

            return true;
        }
 public bool DoStep(NetworkClient networkClient, GameClient client)
 {
     Packet[] packets = networkClient.InputQueue.PopAll(FromServer.ERROR);
     foreach (Packet packet in packets)
     {
         string errorCode = packet["@code"];
         string errorMessage = Errors.GameError.GetErrorMessage(errorCode);
         switch (errorCode)
         {
             case Errors.GameError.E_USER_HAS_DROPPED:
             case Errors.GameError.E_PLAYER_ON_ANOTHER_SERVER:
             case Errors.GameError.E_CONNECTION_ERROR:
                 {
                     networkClient.ThrowError(errorMessage);
                     break;
                 }
             default:
                 {
                     networkClient.OutLogMessage(string.Format("ERROR: {0}", errorMessage));
                     break;
                 }
         }
     }
     return true;
 }
        public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            if (IsReadyForAction)
            {
                DateTime now = DateTime.Now;

                //Collect garbage
                IEnumerable<Packet> packets = networkClient.InputQueue.PeakAll(null).
                    Where(p => now.Subtract(p.ReceiveTime).TotalSeconds >= TTL_OF_PACKER_SEC);
                networkClient.InputQueue.RemoveAll(packets);

                //Generate list of unknown packets
                Packet[] unkPackets = packets.Where(p => !_sysPackets.Contains(p.Type)).ToArray();
                if (unkPackets.Length > 0)
                {
                    //Generate log message
                    StringBuilder message = new StringBuilder();
                    foreach (Packet packet in unkPackets)
                    {
                        message.AppendFormat("{0}{1}", message.Length == 0 ? "" : ", ",
                            packet.Type);
                    }
                    message.Insert(0, "GC -> unknown packets: ");

                    //Send log message
                    networkClient.OutLogMessage(message.ToString());
                }

                _prewGCCollectTime = Environment.TickCount;
            }
            return true;
        }
        public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            //Get game servers list
            List<object> gameServersList = client.AdditionalData[ObjectPropertyName.GAME_SERVER];

            //If servers list is available
            if (gameServersList != null)
            {
                //Connect to the game server
                while (gameServersList.Count > 0)
                {
                    //Pop a first game server in the list
                    string server = (string) gameServersList[0];
                    gameServersList.Remove(server);

                    //Out log message
                    networkClient.OutLogMessage(string.Format("Connecting to the game server: {0}...", server));

                    //Try to connect
                    bool isConnected = networkClient.ConnectToGameServer(server);
                    if (isConnected)
                    {
                        if (networkClient.DoAuthorization())
                        {
                            return true;
                        }
                    }
                }
            }

            //Connection failed
            networkClient.Disconnect();
            return false;
        }
        public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            networkClient.OutLogMessage("Getting my information...");

            //Get my information
            string getInfo = Packet.BuildPacket(FromClient.GET_MY_INFO);
            networkClient.SendData(getInfo);

            //Read and store current location information
            Packet myInfo = networkClient.InputQueue.Pop(FromServer.MY_INFO);
            if (myInfo != null)
            {
                string data = myInfo.Data;

                //Store game client additional info
                Match locationInfo = _regexLocationInfo.Match(data);
                client.AdditionalData.Add(ObjectPropertyName.LOCATION_BUILDING,
                    locationInfo.Groups["B"].Value);
                client.AdditionalData.Add(ObjectPropertyName.LOCATION_X,
                    locationInfo.Groups["X"].Value);
                client.AdditionalData.Add(ObjectPropertyName.LOCATION_Y,
                    locationInfo.Groups["Y"].Value);
                client.AdditionalData.Add(ObjectPropertyName.ID1,
                    locationInfo.Groups["ID1"].Value);
                client.AdditionalData.Add(ObjectPropertyName.ID2,
                    locationInfo.Groups["ID2"].Value);
                client.AdditionalData.Add(ObjectPropertyName.I1,
                    locationInfo.Groups["I1"].Success
                        ? locationInfo.Groups["I1"].Value
                        : "0");

                //Update inventory
                client.InventoryItems = Helper.ParseInventoryItems(data);

                return true;
            }

            networkClient.ThrowError("Failed to getting my info or the connection was terminated");
            return false;
        }
        public bool DoStep(NetworkClient networkClient, GameClient client)
        {
            //Get password key
            Packet data = networkClient.InputQueue.Pop();
            if (data != null)
            {
                string key = data["@s"];

                //Store password key
                client.AdditionalData.Add(ObjectPropertyName.PASSWORD_KEY, key);

                //Get hashed password
                string passwordHash = client.GetPasswordHash(key);

                networkClient.OutLogMessage(
                    string.Format("Trying to login: U = {0}, P = {1}, K = {2}, H = {3}...",
                    client.Login, client.Password, key, passwordHash));

                //Do login
                string login = Packet.BuildPacket(FromClient.LOGIN_DATA,
                    networkClient.LocalIPAddress, client.Version2, client.Version, passwordHash, client.Login);
                networkClient.SendData(login);

                //Get login result
                data = networkClient.InputQueue.Pop();

                if (data != null)
                {
                    //Check on login error
                    string errorCode = data["@code"];
                    if (errorCode != null)
                    {
                        string errorMessage = Errors.GameError.GetErrorMessage(errorCode);
                        switch (errorCode)
                        {
                            //Should be login to another server
                            case Errors.GameError.E_PLAYER_ON_ANOTHER_SERVER:
                                {
                                    networkClient.ThrowError(errorMessage, false);
                                    break;
                                }
                            //General login error
                            default:
                                {
                                    networkClient.ThrowError(errorMessage);
                                    break;
                                }
                        }
                        return false;
                    }

                    //No errors? Continue...
                    string sessionId = data["@ses"];
                    client.AdditionalData.Add(ObjectPropertyName.SESSION_ID, sessionId);

                    networkClient.OutLogMessage(string.Format("User login successful"));

                    return true;
                }
            }

            networkClient.ThrowError("Failed to login or the connection was terminated");
            return false;
        }
        private void InstantBuyItem(NetworkClient networkClient, GameClient client,
            string groupId, int groupPage, XmlNode item, GameItem gameItem, 
            string owner)
        {
            if (item != null && item.Attributes != null)
            {
                XmlAttribute cost = item.Attributes["cost"];
                if (cost != null)
                {
                    float qualityMdf = 1f;
                    float fCost = float.Parse(cost.InnerText);

                    //If InstantPurchaseCost isn`t very low, take into an item quality
                    if (gameItem.FactoryCost > 0 && gameItem.InstantPurchaseCost > 0 &&
                        gameItem.FactoryCost / gameItem.InstantPurchaseCost > 10f)
                    {
                        XmlAttribute quality = item.Attributes["quality"];
                        XmlAttribute maxQuality = item.Attributes["maxquality"];
                        if (quality != null && maxQuality != null)
                        {
                            float fQuality = float.Parse(quality.InnerText);
                            float fMaxQuality = float.Parse(maxQuality.InnerText);
                            qualityMdf = fQuality / fMaxQuality;
                        }
                    }

                    //If an item cost is lower than InstantPurchaseCost, let`s try to buy the item
                    if (fCost <= gameItem.InstantPurchaseCost * qualityMdf)
                    {
                        XmlAttribute id = item.Attributes["id"];
                        XmlAttribute count = item.Attributes["count"];
                        if (id != null && count != null)
                        {
                            string sId = id.InnerText;
                            int iCount = int.Parse(count.InnerText);

                            //Check on antibot maneuvers
                            if (!PassAntibotManeuvers(gameItem, iCount, owner))
                            {
                                return;
                            }

                            //Out log message
                            int totalCost = (int) Math.Ceiling(iCount * fCost);
                            string groupName = _gameItemsGroups[groupId].Name;
                            string message =
                                string.Format("Trying to buy: '{0}', owner: [{1}], group: {2}, page: {3}, count: {4}, cost: {5}, total cost: {6}...",
                                gameItem, owner, groupName, groupPage + 1, iCount, fCost, totalCost);
                            networkClient.OutLogMessage(message);

                            //Try to buy the item
                            //Query params: 1: item ID, 2: count, 3: cost
                            string getGroupsItemsList = Packet.BuildPacket(FromClient.SHOP,
                                Shop.ITEMS_BUY, sId, iCount, fCost);
                            networkClient.SendData(getGroupsItemsList);

                            //Get a purchase result
                            string[] packetTypes = new[] {FromServer.ITEM_ADD_ONE, FromServer.SHOP_ERROR};
                            Packet purchaseResult = networkClient.InputQueue.PopAny(packetTypes);

                            //Check the purchase result
                            if (purchaseResult != null)
                            {
                                switch (purchaseResult.Type)
                                {
                                    //Purchasing is failed
                                    case FromServer.SHOP_ERROR:
                                        {
                                            string errorCode = purchaseResult["@code"];
                                            string errorMessage = Errors.ShopError.GetErrorMessage(errorCode);
                                            networkClient.ThrowError(errorMessage, false);
                                            break;
                                        }
                                    //Successful
                                    default:
                                        {
                                            //Add the item to the inventory or, if it`s bad, out log message
                                            InventoryItem inventoryItem = Helper.ParseInventoryItem(purchaseResult.Data);
                                            if (inventoryItem != null)
                                            {
                                                //Add inventory item record
                                                client.InventoryItems.Add(inventoryItem);

                                                //Join inventory items
                                                GameStep_JoinInventory.DoJoin(networkClient, client);
                                            }
                                            else
                                            {
                                                string errorMessage = string.Format("BUY: BAD INVENTORY ITEM: {0}",
                                                    purchaseResult.Data);
                                                networkClient.ThrowError(errorMessage);
                                            }

                                            //Play alert
                                            _soundPlayer.Play();

                                            //Out log message
                                            networkClient.OutLogMessage("Successful");
                                            break;
                                        }
                                }
                            }
                        }
                    }
                }
            }
        }
        private void SellItem(NetworkClient networkClient, GameClient client,
                              string itemID, string itemName, int itemCount, 
                              float cost, bool isSingleItem)
        {
            string sellItem = isSingleItem
                ? Packet.BuildPacket(FromClient.SHOP, Shop.ITEM_SELL,
                                    itemID, cost)
                : Packet.BuildPacket(FromClient.SHOP, Shop.ITEM_SELL,
                                    itemID, cost, itemCount);
            networkClient.SendData(sellItem);

            string message = string.Format("Trying to sell: '{0}', cost: {1}, count: {2}...",
                                           itemName, cost, itemCount);
            networkClient.OutLogMessage(message);

            //Get a result
            string[] packetTypes = new[] { FromServer.SHOP_OK, FromServer.SHOP_ERROR };
            Packet getResult = networkClient.InputQueue.PopAny(packetTypes);

            //Check the result
            if (getResult != null)
            {
                switch (getResult.Type)
                {
                    //Selling is failed
                    case FromServer.SHOP_ERROR:
                        {
                            string errorCode = getResult["@code"];
                            string errorMessage = Errors.ShopError.GetErrorMessage(errorCode);
                            networkClient.ThrowError(errorMessage, false);
                            break;
                        }
                    //Done
                    default:
                        {
                            //Remove the item from inventory
                            InventoryItem inventoryItem = client.InventoryItems.Find(ii => ii.ID == itemID);
                            if (inventoryItem != null)
                            {
                                client.InventoryItems.Remove(inventoryItem);
                            }

                            //Play alert
                            _soundPlayer.Play();

                            //Out log message
                            networkClient.OutLogMessage("Successful");
                            break;
                        }
                }
            }
        }
        private bool GetOwnItem(NetworkClient networkClient, GameClient client,
                                ShopItem shopItem)
        {
            string message = string.Format("Trying to get: '{0}'...", shopItem.Parent);
            networkClient.OutLogMessage(message);

            //Try to get the item
            //Query params: 1: item ID
            string getGroupsItemsList = Packet.BuildPacket(FromClient.SHOP,
                Shop.ITEM_GET_OWN, shopItem.ID);
            networkClient.SendData(getGroupsItemsList);

            //Get a result
            string[] packetTypes = new[] { FromServer.ITEM_ADD_ONE, FromServer.SHOP_ERROR };
            Packet getResult = networkClient.InputQueue.PopAny(packetTypes);

            //Check the result
            if (getResult != null)
            {
                switch (getResult.Type)
                {
                    //Getting is failed
                    case FromServer.SHOP_ERROR:
                        {
                            string errorCode = getResult["@code"];
                            string errorMessage = Errors.ShopError.GetErrorMessage(errorCode);
                            networkClient.ThrowError(errorMessage, false);
                            break;
                        }
                    //Successful
                    default:
                        {
                            //Add the item to the inventory or, if it`s bad, out log message
                            InventoryItem inventoryItem = Helper.ParseInventoryItem(getResult.Data);
                            if (inventoryItem != null)
                            {
                                //Add the item to inventory
                                client.InventoryItems.Add(inventoryItem);

                                //Join inventory items
                                GameStep_JoinInventory.DoJoin(networkClient, client);

                                //Out log message
                                networkClient.OutLogMessage("Successful");

                                //Done
                                return true;
                            }
                            string errorMessage = string.Format("GET OWN ITEM: BAD INVENTORY ITEM: {0}", getResult.Data);
                            networkClient.ThrowError(errorMessage);
                            break;
                        }
                }
            }

            return false;
        }