private bool AssertAntidumping(ShopItem shopItem, ShopItem[] shopItems) { int nextItemIdx = Array.IndexOf(shopItems, shopItem) + 1; if (nextItemIdx < shopItems.Length) { ShopItem nextItem = shopItems[nextItemIdx]; float costDiff = nextItem.Cost - shopItem.Cost; if ((shopItem.Cost <= 0.4f && costDiff >= 0.05f) || (shopItem.Cost <= 0.9f && costDiff >= 0.1f ) || (shopItem.Cost <= 5 && costDiff >= 0.5f ) || (shopItem.Cost <= 15 && costDiff >= 1f ) || (shopItem.Cost <= 30 && costDiff >= 2f ) || (shopItem.Cost <= 100 && costDiff >= 3f ) || (shopItem.Cost <= 200 && costDiff >= 4f ) || (shopItem.Cost <= 500 && costDiff >= 10f ) || (shopItem.Cost <= 999 && costDiff >= 20f) ) { return false; } } return true; }
private void DoDumping(NetworkClient networkClient, GameClient client, ShopItem myItem, bool itemInAuc) { bool needToSellItem = !itemInAuc; //Need to join if (itemInAuc && !myItem.IsSingle) { InventoryItem[] inventoryItem = client.InventoryItems.Where ( ii => ii.Ident == myItem.Ident ).ToArray(); needToSellItem = inventoryItem.Length > 0; } //Need to dumping ShopItem[] shopItems = _auctionItems[myItem.SubGroupID].Where ( si => si.Ident == myItem.Ident ).ToArray(); needToSellItem |= shopItems.Length > 0; if (needToSellItem) { //Calculate target cost float itemCost = CalculateItemCost(client, myItem, shopItems); if (itemCost > 0f) { //Prevent to sell bla-bla if (!itemInAuc && !myItem.IsSingle && ((itemCost <= 1f && myItem.Count <= 100 ) || (itemCost <= 20f && myItem.Count <= 50 ) || (itemCost <= 50f && myItem.Count <= 10 ))) { return; } string itemID = myItem.ID; string itemName = myItem.Parent.ToString(); int itemCount = myItem.Count; //Get the item from auction if (itemInAuc) { if (!GetOwnItem(networkClient, client, myItem)) { return; } InventoryItem inventoryItem = client.InventoryItems.FirstOrDefault ( ii => ii.ID == myItem.ID ); if (inventoryItem == null) { return; } itemID = inventoryItem.ID; itemCount = inventoryItem.Count; } //Don`t sell the item if it`s cost lower than 50 if (itemCount > 1 && itemCount * itemCost < 50) { return; } //Sell the item SellItem(networkClient, client, itemID, itemName, itemCount, itemCost, myItem.IsSingle); } } }
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; }
private float CalculateItemCost(GameClient client, ShopItem myItem, ShopItem[] shopItems) { //Get basic item cost float cost = myItem.FactoryCost > 0f ? myItem.FactoryCost * 1.5f : 0f; //Last shop item with a lower quality ShopItem lqShopItem; foreach (ShopItem shopItem in shopItems) { //Detect "antidumping" if (!AssertAntidumping(shopItem, shopItems)) { continue; } if (!myItem.IsSingle) { if (shopItem.IsOwnItem(client.Login)) { if (myItem.ID == shopItem.ID) { return 0f; } continue; } //Calculate subs. value float subsValue = shopItem.Cost <= 50f ? 0.01f : 1f; //Calculate a count ratio double countRatio = myItem.Count / shopItem.Count; //Calculate a shop item cost float shopItemCost = shopItem.Count * shopItem.Cost; //My item is more expensive if (myItem.Cost > shopItem.Cost && shopItemCost > 100 && countRatio < 10f) { return shopItem.Cost - subsValue; } //Equal cost if (myItem.Cost == shopItem.Cost) { return countRatio < 1.3f ? shopItem.Cost - subsValue : 0f; } //My item is chiper if (myItem.Cost < shopItem.Cost) { cost = countRatio < 1.3f ? shopItem.Cost - subsValue : shopItem.Cost; return cost != myItem.Cost ? cost : 0f; } } else { if (shopItem.IsOwnItem(client.Login)) { return 0f; } if (shopItem.Quality < myItem.Quality) { continue; } lqShopItem = shopItem; if (lqShopItem.Quality == myItem.Quality) { return lqShopItem.Cost - 1f; } Dictionary<float, List<ShopItem>> dictShopItems = new Dictionary<float, List<ShopItem>>(); foreach (ShopItem uniqueShopItem in shopItems) { List<ShopItem> list; if (!dictShopItems.ContainsKey(uniqueShopItem.Quality)) { list = new List<ShopItem>(); dictShopItems.Add(uniqueShopItem.Quality, list); } else { list = dictShopItems[uniqueShopItem.Quality]; } list.Add(uniqueShopItem); } List<ShopItem> resultList = new List<ShopItem>(); foreach (List<ShopItem> list in dictShopItems.Values) { int itemsCnt = list.Count; if (itemsCnt >= 3) { int truncNum = (int)Math.Ceiling(itemsCnt * 0.2f); int truncCnt = Math.Max(itemsCnt - (truncNum * 2), 1); resultList.AddRange(list.Skip(truncNum).Take(truncCnt)); } else { resultList.AddRange(list); } } if (resultList.Count < 5) { return 0f; } float sumCost = 0f, sumQuality = 0f; foreach (ShopItem resultShopItem in resultList) { sumCost += resultShopItem.Cost; sumQuality += resultShopItem.Quality; } double qualityUnitCost = sumQuality / sumCost; float qualityDiff = lqShopItem.Quality - myItem.Quality; float newCost = lqShopItem.Cost - ((float)qualityUnitCost * qualityDiff); return newCost; } } return cost; }