// Collects information about item counts and minimum prices to SameItemInfo and updates EligibleItems - a list with new items eligible for bot to buy and bid // Returns count of items in AH that were eligible for being bought or bidded on by ahbot buyer (EligibleItems size) uint32 AuctionBotBuyer::GetItemInformation(BuyerConfiguration& config) { config.SameItemInfo.clear(); time_t now = time(nullptr); uint32 count = 0; AuctionHouseObject* house = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = house->GetAuctionsBegin(); itr != house->GetAuctionsEnd(); ++itr) { AuctionEntry* entry = itr->second; if (!entry->owner) continue; // Skip auctions owned by AHBot Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow); if (!item) continue; BuyerItemInfo& itemInfo = config.SameItemInfo[item->GetEntry()]; // Update item entry's count and total bid prices // This can be used later to determine the prices and chances to bid uint32 itemBidPrice = entry->startbid / item->GetCount(); itemInfo.TotalBidPrice = itemInfo.TotalBidPrice + itemBidPrice; itemInfo.BidItemCount++; // Set minimum bid price if (!itemInfo.MinBidPrice) itemInfo.MinBidPrice = itemBidPrice; else itemBidPrice = std::min(itemInfo.MinBidPrice, itemBidPrice); // Set minimum buyout price if item has buyout if (entry->buyout) { // Update item entry's count and total buyout prices // This can be used later to determine the prices and chances to buyout uint32 itemBuyPrice = entry->buyout / item->GetCount(); itemInfo.TotalBuyPrice = itemInfo.TotalBuyPrice + itemBuyPrice; itemInfo.BuyItemCount++; if (!itemInfo.MinBuyPrice) itemInfo.MinBuyPrice = itemBuyPrice; else itemInfo.MinBuyPrice = std::min(itemInfo.MinBuyPrice, itemBuyPrice); } // Add/update EligibleItems if: // * no bid // * bid from player if (!entry->bid || entry->bidder) { config.EligibleItems[entry->Id].LastExist = now; config.EligibleItems[entry->Id].AuctionId = entry->Id; ++count; } } TC_LOG_DEBUG("ahbot", "AHBot: %u items added to buyable/biddable vector for ah type: %u", count, config.GetHouseType()); TC_LOG_DEBUG("ahbot", "AHBot: SameItemInfo size = %u", (uint32)config.SameItemInfo.size()); return count; }
void InAuctionItemsBag::Load() { AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(auctionId); for (AuctionHouseObject::AuctionEntryMap::iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) { ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itr->second->itemEntry); if (!proto) continue; Add(proto); } }
//this void sends player info about his auctions void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+4); uint32 listfrom; uint64 guid; recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4) ); data << (uint32) 0; // amount place holder uint32 count = 0; uint32 totalcount = 0; for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; if( Aentry && Aentry->owner == _player->GetGUIDLow() ) { if(SendAuctionInfo(data, itr->second)) ++count; ++totalcount; } } data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 0; SendPacket(&data); }
//this void is called when player clicks on search button void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+4+1+1+1+4+4+4+4+1); std::string searchedname, name; uint8 levelmin, levelmax, usable, location; uint32 count, totalcount, listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; uint64 guid; recv_data >> guid; recv_data >> listfrom; // start, used for page control listing by 50 elements recv_data >> searchedname; // recheck with known string size CHECK_PACKET_SIZE(recv_data,8+4+(searchedname.size()+1)+1+1+4+4+4+4+1); recv_data >> levelmin >> levelmax; recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; recv_data >> quality >> usable; Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); location = AuctioneerFactionToLocation(pCreature->getFaction()); AuctionHouseObject * mAuctions; mAuctions = objmgr.GetAuctionsMap( location ); //sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) ); count = 0; totalcount = 0; data << (uint32) 0; // converting string that we try to find to lower case std::wstring wsearchedname; if(!Utf8toWStr(searchedname,wsearchedname)) return; wstrToLower(wsearchedname); for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; Item *item = objmgr.GetAItem(Aentry->item_guidlow); if( item ) { ItemPrototype const *proto = item->GetProto(); if( proto ) { if( auctionMainCategory == (0xffffffff) || proto->Class == auctionMainCategory ) { if( auctionSubCategory == (0xffffffff) || proto->SubClass == auctionSubCategory ) { if( auctionSlotID == (0xffffffff) || proto->InventoryType == auctionSlotID ) { if( quality == (0xffffffff) || proto->Quality == quality ) { if( usable == (0x00) || _player->CanUseItem( item ) == EQUIP_ERR_OK ) { if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) ) { name = proto->Name1; // local name int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId); if (il) { if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) name = il->Name[loc_idx]; } } if(name.empty()) continue; if( wsearchedname.empty() || Utf8FitTo(name, wsearchedname) ) { if ((count < 50) && (totalcount >= listfrom)) { ++count; SendAuctionInfo( data, Aentry); } ++totalcount; } } } } } } } } } } data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 300; // unk 2.3.0 const? SendPacket(&data); }
void AuctionHouseBotCommands(uint32 command, uint32 ahMapID, uint32 col, char* args) { AHBConfig *config; switch (ahMapID) { case 2: config = &AllianceConfig; break; case 6: config = &HordeConfig; break; case 7: config = &NeutralConfig; break; } std::string color; switch (col) { case AHB_GREY: color = "grey"; break; case AHB_WHITE: color = "white"; break; case AHB_GREEN: color = "green"; break; case AHB_BLUE: color = "blue"; break; case AHB_PURPLE: color = "purple"; break; default: break; } switch (command) { case 0: //ahexpire { AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(ahMapID); AuctionHouseObject::AuctionEntryMap::iterator itr; itr = auctionHouse->GetAuctionsBegin(); while (itr != auctionHouse->GetAuctionsEnd()) { if (itr->second->owner == AHBplayerGUID) itr->second->time = sWorld.GetGameTime(); ++itr; } }break; case 1: //min items { char * param1 = strtok(args, " "); uint32 minItems = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET minitems = '%u' WHERE auctionhouse = '%u'", minItems, ahMapID); config->SetMinItems(minItems); }break; case 2: //max items { char * param1 = strtok(args, " "); uint32 maxItems = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxitems = '%u' WHERE auctionhouse = '%u'", maxItems, ahMapID); config->SetMaxItems(maxItems); }break; case 3: //min time { char * param1 = strtok(args, " "); uint32 minTime = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET mintime = '%u' WHERE auctionhouse = '%u'", minTime, ahMapID); config->SetMinTime(minTime); }break; case 4: //max time { char * param1 = strtok(args, " "); uint32 maxTime = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxtime = '%u' WHERE auctionhouse = '%u'", maxTime, ahMapID); config->SetMaxTime(maxTime); }break; case 5: //percentages { char * param1 = strtok(args, " "); char * param2 = strtok(NULL, " "); char * param3 = strtok(NULL, " "); char * param4 = strtok(NULL, " "); char * param5 = strtok(NULL, " "); char * param6 = strtok(NULL, " "); char * param7 = strtok(NULL, " "); char * param8 = strtok(NULL, " "); uint32 wtg = (uint32) strtoul(param1, NULL, 0); uint32 gtg = (uint32) strtoul(param2, NULL, 0); uint32 btg = (uint32) strtoul(param3, NULL, 0); uint32 ptg = (uint32) strtoul(param4, NULL, 0); uint32 wi = (uint32) strtoul(param5, NULL, 0); uint32 gi = (uint32) strtoul(param6, NULL, 0); uint32 bi = (uint32) strtoul(param7, NULL, 0); uint32 pi = (uint32) strtoul(param8, NULL, 0); CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhitetradegoods = '%u' WHERE auctionhouse = '%u'", wtg, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreentradegoods = '%u' WHERE auctionhouse = '%u'", gtg, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentbluetradegoods = '%u' WHERE auctionhouse = '%u'", btg, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentpurpletradegoods = '%u' WHERE auctionhouse = '%u'", ptg, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhiteitems = '%u' WHERE auctionhouse = '%u'", wi, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreenitems = '%u' WHERE auctionhouse = '%u'", gi, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentblueitems = '%u' WHERE auctionhouse = '%u'", bi, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentpurpleitems = '%u' WHERE auctionhouse = '%u'", pi, ahMapID); CharacterDatabase.CommitTransaction(); config->SetPercentages(wtg, gtg, btg, ptg, wi, gi, bi, pi); }break; case 6: //min prices { char * param1 = strtok(args, " "); uint32 minPrice = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET minprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), minPrice, ahMapID); config->SetMinPrice(col, minPrice); }break; case 7: //max prices { char * param1 = strtok(args, " "); uint32 maxPrice = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxPrice, ahMapID); config->SetMaxPrice(col, maxPrice); }break; case 8: //min bid price { char * param1 = strtok(args, " "); uint32 minBidPrice = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET minbidprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), minBidPrice, ahMapID); config->SetMinBidPrice(col, minBidPrice); }break; case 9: //max bid price { char * param1 = strtok(args, " "); uint32 maxBidPrice = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxbidprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxBidPrice, ahMapID); config->SetMaxBidPrice(col, maxBidPrice); }break; case 10: //max stacks { char * param1 = strtok(args, " "); uint32 maxStack = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxstack%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxStack, ahMapID); config->SetMaxStack(col, maxStack); }break; case 11: //buyer bid prices { char * param1 = strtok(args, " "); uint32 buyerPrice = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), buyerPrice, ahMapID); config->SetBuyerPrice(col, buyerPrice); }break; case 12: //buyer bidding interval { char * param1 = strtok(args, " "); uint32 bidInterval = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerbiddinginterval = '%u' WHERE auctionhouse = '%u'", bidInterval, ahMapID); config->SetBiddingInterval(bidInterval); }break; case 13: //buyer bids per interval { char * param1 = strtok(args, " "); uint32 bidsPerInterval = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerbidsperinterval = '%u' WHERE auctionhouse = '%u'", bidsPerInterval, ahMapID); config->SetBidsPerInterval(bidsPerInterval); }break; default: break; } }
//called when player lists his bids void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+4+4); uint64 guid; //NPC guid uint32 listfrom; //page of auctions uint32 outbiddedCount; //count of outbidded auctions recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) recv_data >> outbiddedCount; if (recv_data.size() != (16 + outbiddedCount * 4 )) { sLog.outError("Client sent bad opcode!!! with count: %u and size : %d (mustbe: %d", outbiddedCount, recv_data.size(),(16 + outbiddedCount * 4 )); outbiddedCount = 0; } Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) ); Player *pl = GetPlayer(); data << (uint32) 0; //add 0 as count uint32 count = 0; uint32 totalcount = 0; while ( outbiddedCount > 0) //add all data, which client requires { --outbiddedCount; uint32 outbiddedAuctionId; recv_data >> outbiddedAuctionId; AuctionEntry * auction = mAuctions->GetAuction( outbiddedAuctionId ); if ( auction && SendAuctionInfo(data, auction)) { ++totalcount; ++count; } } for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; if( Aentry && Aentry->bidder == pl->GetGUIDLow() ) { if (SendAuctionInfo(data, itr->second)) ++count; ++totalcount; } } data.put<uint32>( 0, count ); // add count to placeholder data << totalcount; data << (uint32)300; //unk 2.3.0 SendPacket(&data); }
static void addNewAuctions(Player *AHBplayer, AHBConfig *config) { if (!AHBSeller) return; AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID()); uint32 items = 0; uint32 minItems = config->GetMinItems(); uint32 maxItems = config->GetMaxItems(); uint32 auctions = auctionHouse->Getcount(); if (auctions >= minItems) return; if (auctions <= maxItems) { if ((maxItems - auctions) > ItemsPerCycle) items = ItemsPerCycle; else items = (maxItems - auctions); } uint32 wtgbin = config->GetPercents(AHB_WHITE_TG); uint32 gtgbin = config->GetPercents(AHB_GREEN_TG); uint32 btgbin = config->GetPercents(AHB_BLUE_TG); uint32 ptgbin = config->GetPercents(AHB_PURPLE_TG); uint32 wibin = config->GetPercents(AHB_WHITE_I); uint32 gibin = config->GetPercents(AHB_GREEN_I); uint32 bibin = config->GetPercents(AHB_BLUE_I); uint32 pibin = config->GetPercents(AHB_PURPLE_I); uint32 total = wtgbin + gtgbin + btgbin + ptgbin + wibin + gibin + bibin + pibin; uint32 pItems = 0; uint32 bItems = 0; uint32 gItems = 0; uint32 wItems = 0; uint32 pTGoods = 0; uint32 bTGoods = 0; uint32 gTGoods = 0; uint32 wTGoods = 0; for (AuctionHouseObject::AuctionEntryMap::iterator itr = auctionHouse->GetAuctionsBegin();itr != auctionHouse->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; Item *item = objmgr.GetAItem(Aentry->item_guidlow); if( item ) { ItemPrototype const *prototype = item->GetProto(); if( prototype ) { switch (prototype->Quality) { case 0: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) wTGoods = wTGoods + 1; else wItems = wItems + 1; break; case 1: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) wTGoods = wTGoods + 1; else wItems = wItems + 1; break; case 2: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) gTGoods = gTGoods + 1; else gItems = gItems + 1; break; case 3: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) bTGoods = bTGoods + 1; else bItems = bItems + 1; break; case 4: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) pTGoods = pTGoods + 1; else pItems = pItems + 1; break; } } } } // only insert a few at a time, so as not to peg the processor for (uint32 cnt = 1;cnt <= items;cnt++) { uint32 itemID = 0; while (itemID == 0) { uint32 choice = urand(1, 8); switch (choice) { case 1: { if ((purpleItems.size() > 0) && (pItems < pibin)) { itemID = purpleItems[urand(0, purpleItems.size() - 1)]; pItems = pItems + 1; break; } } case 2: { if ((blueItems.size() > 0) && (bItems < bibin)) { itemID = blueItems[urand(0, blueItems.size() - 1)]; bItems = bItems + 1; break; } } case 3: { if ((greenItems.size() > 0) && (gItems < gibin)) { itemID = greenItems[urand(0, greenItems.size() - 1)]; gItems = gItems + 1; break; } } case 4: { if ((whiteItems.size() > 0) && (wItems < wibin)) { itemID = whiteItems[urand(0, whiteItems.size() - 1)]; wItems = wItems + 1; break; } } case 5: { if ((purpleTradeGoods.size() > 0) && (pTGoods < ptgbin)) { itemID = purpleTradeGoods[urand(0, purpleTradeGoods.size() - 1)]; pTGoods = pTGoods + 1; break; } } case 6: { if ((blueTradeGoods.size() > 0) && (bTGoods < btgbin)) { itemID = blueTradeGoods[urand(0, blueTradeGoods.size() - 1)]; bTGoods = bTGoods + 1; break; } } case 7: { if ((greenTradeGoods.size() > 0) && (gTGoods < gtgbin)) { itemID = greenTradeGoods[urand(0, greenTradeGoods.size() - 1)]; gTGoods = gTGoods + 1; break; } } case 8: { if ((whiteTradeGoods.size() > 0) && (wTGoods < wtgbin)) { itemID = whiteTradeGoods[urand(0, whiteTradeGoods.size() - 1)]; wTGoods = wTGoods + 1; break; } } default: { break; } } } ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID); if (prototype == NULL) { sLog.outString("AuctionHouseBot: Huh?!?! prototype == NULL"); continue; } Item* item = Item::CreateItem(itemID, 1, AHBplayer); item->AddToUpdateQueueOf(AHBplayer); if (item == NULL) { sLog.outString("AuctionHouseBot: Item::CreateItem() returned NULL"); break; } uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); if (randomPropertyId != 0) item->SetItemRandomProperties(randomPropertyId); uint32 buyoutPrice; uint32 bidPrice = 0; uint32 stackCount = urand(1, item->GetMaxStackCount()); switch (SellMethod) { case 0: buyoutPrice = prototype->SellPrice * item->GetCount(); break; case 1: buyoutPrice = prototype->BuyPrice * item->GetCount(); break; default: buyoutPrice = 0; break; } switch (prototype->Quality) { case 1: if (config->GetMaxStack(AHB_WHITE) != 0) { stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_WHITE))); } buyoutPrice *= urand(config->GetMinPrice(AHB_WHITE), config->GetMaxPrice(AHB_WHITE)) * stackCount; buyoutPrice /= 100; bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_WHITE), config->GetMaxBidPrice(AHB_WHITE)); bidPrice /= 100; break; case 2: if (config->GetMaxStack(AHB_GREEN) != 0) { stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_GREEN))); } buyoutPrice *= urand(config->GetMinPrice(AHB_GREEN), config->GetMaxPrice(AHB_GREEN)) * stackCount; buyoutPrice /= 100; bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_GREEN), config->GetMaxBidPrice(AHB_GREEN)); bidPrice /= 100; break; case 3: if (config->GetMaxStack(AHB_BLUE) != 0) { stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_BLUE))); } buyoutPrice *= urand(config->GetMinPrice(AHB_BLUE), config->GetMaxPrice(AHB_BLUE)) * stackCount; buyoutPrice /= 100; bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_BLUE), config->GetMaxBidPrice(AHB_BLUE)); bidPrice /= 100; break; case 4: if (config->GetMaxStack(AHB_PURPLE) != 0) { stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_PURPLE))); } buyoutPrice *= urand(config->GetMinPrice(AHB_PURPLE), config->GetMaxPrice(AHB_PURPLE)) * stackCount; buyoutPrice /= 100; bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_PURPLE), config->GetMaxBidPrice(AHB_PURPLE)); bidPrice /= 100; break; } item->SetCount(stackCount); AuctionEntry* auctionEntry = new AuctionEntry; auctionEntry->Id = objmgr.GenerateAuctionID(); auctionEntry->auctioneer = 0; auctionEntry->item_guidlow = item->GetGUIDLow(); auctionEntry->item_template = item->GetEntry(); auctionEntry->owner = AHBplayer->GetGUIDLow(); auctionEntry->startbid = bidPrice; auctionEntry->buyout = buyoutPrice; auctionEntry->bidder = 0; auctionEntry->bid = 0; auctionEntry->deposit = 0; auctionEntry->location = config->GetAHID(); auctionEntry->time = (time_t) (urand(config->GetMinTime(), config->GetMaxTime()) * 60 * 60 + time(NULL)); item->SaveToDB(); item->RemoveFromUpdateQueueOf(AHBplayer); objmgr.AddAItem(item); auctionHouse->AddAuction(auctionEntry); CharacterDatabase.PExecute("INSERT INTO `auctionhouse` (`id`," "`auctioneerguid`,`itemguid`,`item_template`," "`itemowner`,`buyoutprice`,`time`,`buyguid`," "`lastbid`,`startbid`,`deposit`,`location`) " "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', " "'" I64FMTD "', '%u', '%u', '%u', '%u', '%u')", auctionEntry->Id, auctionEntry->auctioneer, auctionEntry->item_guidlow, auctionEntry->item_template, auctionEntry->owner, auctionEntry->buyout, (uint64) auctionEntry->time, auctionEntry->bidder, auctionEntry->bid, auctionEntry->startbid, auctionEntry->deposit, auctionEntry->location); } }
static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session) { if (!AHBBuyer) return; // Fetches content of selected AH AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID()); AuctionHouseObject::AuctionEntryMap::iterator itr; itr = auctionHouse->GetAuctionsBegin(); vector<uint32> possibleBids; while (itr != auctionHouse->GetAuctionsEnd()) { AuctionHouseObject::AuctionEntryMap::iterator tmp = itr; ++itr; // Check if the auction is ours // if it is, we skip this iteration. if(tmp->second->owner == AHBplayerGUID) { continue; } // Check that we haven't bidded in this auction already. if(tmp->second->bidder != AHBplayerGUID) { uint32 tmpdata = tmp->second->Id; possibleBids.push_back(tmpdata); } } // Do we have anything to bid? If not, stop here. if(possibleBids.empty()) { return; } // Choose random auction from possible auctions uint32 auctionID = possibleBids[urand(0, possibleBids.size() - 1)]; // from auctionhouse.cpp, creates auction pointer & player pointer AuctionEntry* auction = auctionHouse->GetAuction(auctionID); // get exact item information Item *pItem = objmgr.GetAItem(auction->item_guidlow); if (!pItem) { sLog.outError("Item doesn't exists, perhaps bought already?"); return; } // get item prototype ItemPrototype const* prototype = objmgr.GetItemPrototype(auction->item_template); // check which price we have to use, startbid or if it is bidded already if(debug_Out) {sLog.outError("Auction Number: %u", auction->Id);} if(debug_Out) {sLog.outError("Item Template: %u", auction->item_template);} if(debug_Out) {sLog.outError("Buy Price: %u", prototype->BuyPrice);} if(debug_Out) {sLog.outError("Sell Price: %u", prototype->SellPrice);} if(debug_Out) {sLog.outError("Quality: %u", prototype->Quality);} uint32 currentprice; if(auction->bid) { currentprice = auction->bid; if(debug_Out) {sLog.outError("Current Price: %u", auction->bid);} } else { currentprice = auction->startbid; if(debug_Out) {sLog.outError("Current Price: %u", auction->startbid);} } uint32 bidprice; // Prepare portion from maximum bid uint32 tmprate2 = urand(0, 100); double tmprate = static_cast<double>(tmprate2); if(debug_Out) {sLog.outError("tmprate: %f", tmprate);} double bidrate = tmprate / 100; if(debug_Out) {sLog.outError("bidrate: %f", bidrate);} long double bidMax = 0; // check that bid has acceptable value and take bid based on vendorprice, stacksize and quality switch (BuyMethod) { case 0: switch (prototype->Quality) { case 0: if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY)) { bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY); } break; case 1: if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE)) { bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE); } break; case 2: if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN)) { bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN); } break; case 3: if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE)) { bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE); } break; case 4: if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE)) { bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE); } break; default: // quality is something it shouldn't be, let's get out of here if(debug_Out) {sLog.outError("bidMax(fail): %f", bidMax);} return; break; } break; case 1: switch (prototype->Quality) { case 0: if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY)) { bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY); } break; case 1: if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE)) { bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE); } break; case 2: if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN)) { bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN); } break; case 3: if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE)) { bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE); } break; case 4: if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE)) { bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE); } break; default: // quality is something it shouldn't be, let's get out of here if(debug_Out) {sLog.outError("bidMax(fail): %f", bidMax);} return; break; } break; default: bidMax = 0; break; } if(debug_Out) {sLog.outError("bidMax(succeed): %f", bidMax);} // check some special items, and do recalculating to their prices switch (prototype->Class) { // ammo case 6: bidMax = 0; break; default: break; } if(bidMax == 0) { // quality check failed to get bidmax, let's get out of here return; } // Calculate our bid long double bidvalue = currentprice + ( (bidMax - currentprice) * bidrate); if(debug_Out) {sLog.outError("bidvalue: %f", bidvalue);} // Convert to uint32 bidprice = static_cast<uint32>(bidvalue); if(debug_Out) {sLog.outError("bidprice: %u", bidprice);} // Check our bid is high enough to be valid. If not, correct it to minimum. if((currentprice + objmgr.GetAuctionOutBid(currentprice)) > bidprice) { bidprice = currentprice + objmgr.GetAuctionOutBid(currentprice); if(debug_Out) {sLog.outError("bidprice(>): %u", bidprice);} } // Check wether we do normal bid, or buyout if ((bidprice < auction->buyout) || (auction->buyout == 0)) { if (auction->bidder > 0) { if ( auction->bidder == AHBplayer->GetGUIDLow() ) { //pl->ModifyMoney( -int32(price - auction->bid)); } else { // mail to last bidder and return money session->SendAuctionOutbiddedMail( auction , bidprice ); //pl->ModifyMoney( -int32(price) ); } } auction->bidder = AHBplayer->GetGUIDLow(); auction->bid = bidprice; // Saving auction into database CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); } else { //buyout if (AHBplayer->GetGUIDLow() == auction->bidder ) { //pl->ModifyMoney(-int32(auction->buyout - auction->bid)); } else { //pl->ModifyMoney(-int32(auction->buyout)); if ( auction->bidder ) { session->SendAuctionOutbiddedMail( auction, auction->buyout ); } } auction->bidder = AHBplayer->GetGUIDLow(); auction->bid = auction->buyout; // Send mails to buyer & seller objmgr.SendAuctionSuccessfulMail( auction ); objmgr.SendAuctionWonMail( auction ); // Remove item from auctionhouse objmgr.RemoveAItem(auction->item_guidlow); // Remove auction auctionHouse->RemoveAuction(auction->Id); // Remove from database CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); delete auction; } }
void AuctionHouseBot::Rebuild(bool all) { for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) { AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i)); for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) if (!itr->second->owner || sAuctionBotConfig->IsBotChar(itr->second->owner)) // ahbot auction if (all || itr->second->bid == 0) // expire now auction if no bid or forced itr->second->expire_time = sWorld->GetGameTime(); } }
void AuctionHouseBot::PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo) { for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) { statusInfo[i].ItemsCount = 0; for (int j = 0; j < MAX_AUCTION_QUALITY; ++j) statusInfo[i].QualityInfo[j] = 0; AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i)); for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) { AuctionEntry* auctionEntry = itr->second; if (Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow)) { ItemTemplate const* prototype = item->GetTemplate(); if (!auctionEntry->owner || sAuctionBotConfig->IsBotChar(auctionEntry->owner)) // Add only ahbot items { if (prototype->Quality < MAX_AUCTION_QUALITY) ++statusInfo[i].QualityInfo[prototype->Quality]; ++statusInfo[i].ItemsCount; } } } } }
uint32 AuctionBotBuyer::GetBuyableEntry(BuyerConfiguration& config) { config.SameItemInfo.clear(); uint32 count = 0; time_t now = time(nullptr); AuctionHouseObject* house = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = house->GetAuctionsBegin(); itr != house->GetAuctionsEnd(); ++itr) { AuctionEntry* entry = itr->second; Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow); if (item) { ItemTemplate const * prototype = item->GetTemplate(); if (prototype) { ++config.SameItemInfo[item->GetEntry()].ItemCount; // Structure constructor will make sure Element are correctly initialized if entry is created here. config.SameItemInfo[item->GetEntry()].BuyPrice = config.SameItemInfo[item->GetEntry()].BuyPrice + (itr->second->buyout / item->GetCount()); config.SameItemInfo[item->GetEntry()].BidPrice = config.SameItemInfo[item->GetEntry()].BidPrice + (itr->second->startbid / item->GetCount()); if (itr->second->buyout != 0) { if (itr->second->buyout / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBuyPrice) config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount(); else if (config.SameItemInfo[item->GetEntry()].MinBuyPrice == 0) config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount(); } if (itr->second->startbid / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBidPrice) config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount(); else if (config.SameItemInfo[item->GetEntry()].MinBidPrice == 0) config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount(); if (!entry->owner) { if (entry->bid != 0 && entry->bidder) // Add bid by player { config.CheckedEntry[entry->Id].LastExist = now; config.CheckedEntry[entry->Id].AuctionId = entry->Id; ++count; } } else { if (entry->bid != 0) { if (entry->bidder) { config.CheckedEntry[entry->Id].LastExist = now; config.CheckedEntry[entry->Id].AuctionId = entry->Id; ++count; } } else { config.CheckedEntry[entry->Id].LastExist = now; config.CheckedEntry[entry->Id].AuctionId = entry->Id; ++count; } } } } } TC_LOG_DEBUG("ahbot", "AHBot: %u items added to buyable vector for ah type: %u", count, config.GetHouseType()); TC_LOG_DEBUG("ahbot", "AHBot: SameItemInfo size = %u", (uint32)config.SameItemInfo.size()); return count; }