diff options
-rw-r--r-- | src/game/AuctionHouseBot.cpp | 36 | ||||
-rw-r--r-- | src/game/AuctionHouseHandler.cpp | 235 | ||||
-rw-r--r-- | src/game/AuctionHouseMgr.h | 107 | ||||
-rw-r--r-- | src/game/Makefile.am | 1 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 414 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 57 | ||||
-rw-r--r-- | src/game/PlayerDump.h | 23 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 4 | ||||
-rw-r--r-- | src/game/World.cpp | 57 | ||||
-rw-r--r-- | src/game/WorldSession.h | 1 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.cpp | 4 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.h | 1 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 10 | ||||
-rw-r--r-- | src/shared/Database/DBCfmt.cpp | 1 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 | ||||
-rw-r--r-- | win/VC71/game.vcproj | 3 | ||||
-rw-r--r-- | win/VC80/game.vcproj | 4 | ||||
-rw-r--r-- | win/VC90/game.vcproj | 4 |
18 files changed, 219 insertions, 745 deletions
diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp index 4830dcefce4..94ee49c54be 100644 --- a/src/game/AuctionHouseBot.cpp +++ b/src/game/AuctionHouseBot.cpp @@ -62,7 +62,7 @@ static void addNewAuctions(Player *AHBplayer, AHBConfig *config) { if (!AHBSeller) return; - AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID()); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMapByLocation(config->GetAHID()); uint32 items = 0; uint32 minItems = config->GetMinItems(); uint32 maxItems = config->GetMaxItems(); @@ -98,7 +98,7 @@ static void addNewAuctions(Player *AHBplayer, AHBConfig *config) for (AuctionHouseObject::AuctionEntryMap::iterator itr = auctionHouse->GetAuctionsBegin();itr != auctionHouse->GetAuctionsEnd();++itr) { AuctionEntry *Aentry = itr->second; - Item *item = objmgr.GetAItem(Aentry->item_guidlow); + Item *item = auctionmgr.GetAItem(Aentry->item_guidlow); if( item ) { ItemPrototype const *prototype = item->GetProto(); @@ -328,31 +328,29 @@ static void addNewAuctions(Player *AHBplayer, AHBConfig *config) 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)); + auctionEntry->expire_time = (time_t) (urand(config->GetMinTime(), config->GetMaxTime()) * 60 * 60 + time(NULL)); item->SaveToDB(); item->RemoveFromUpdateQueueOf(AHBplayer); - objmgr.AddAItem(item); + auctionmgr.AddAItem(item); auctionHouse->AddAuction(auctionEntry); CharacterDatabase.PExecute("INSERT INTO `auctionhouse` (`id`," "`auctioneerguid`,`itemguid`,`item_template`," "`itemowner`,`buyoutprice`,`time`,`buyguid`," - "`lastbid`,`startbid`,`deposit`,`location`) " + "`lastbid`,`startbid`,`deposit`) " "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', " - "'" I64FMTD "', '%u', '%u', '%u', '%u', '%u')", + "'" I64FMTD "', '%u', '%u', '%u', '%u')", auctionEntry->Id, auctionEntry->auctioneer, auctionEntry->item_guidlow, auctionEntry->item_template, auctionEntry->owner, auctionEntry->buyout, - (uint64) auctionEntry->time, + (uint64) auctionEntry->expire_time, auctionEntry->bidder, auctionEntry->bid, auctionEntry->startbid, - auctionEntry->deposit, - auctionEntry->location); + auctionEntry->deposit); } } @@ -362,7 +360,7 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World return; // Fetches content of selected AH - AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID()); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMapByLocation(config->GetAHID()); AuctionHouseObject::AuctionEntryMap::iterator itr; itr = auctionHouse->GetAuctionsBegin(); @@ -399,7 +397,7 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World AuctionEntry* auction = auctionHouse->GetAuction(auctionID); // get exact item information - Item *pItem = objmgr.GetAItem(auction->item_guidlow); + Item *pItem = auctionmgr.GetAItem(auction->item_guidlow); if (!pItem) { sLog.outError("Item doesn't exists, perhaps bought already?"); @@ -564,9 +562,9 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World {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) + if((currentprice + auction->GetAuctionOutBid()) > bidprice) { - bidprice = currentprice + objmgr.GetAuctionOutBid(currentprice); + bidprice = currentprice + auction->GetAuctionOutBid(); if(debug_Out) {sLog.outError("bidprice(>): %u", bidprice);} } @@ -614,11 +612,11 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World auction->bid = auction->buyout; // Send mails to buyer & seller - objmgr.SendAuctionSuccessfulMail( auction ); - objmgr.SendAuctionWonMail( auction ); + auctionmgr.SendAuctionSuccessfulMail( auction ); + auctionmgr.SendAuctionWonMail( auction ); // Remove item from auctionhouse - objmgr.RemoveAItem(auction->item_guidlow); + auctionmgr.RemoveAItem(auction->item_guidlow); // Remove auction auctionHouse->RemoveAuction(auction->Id); // Remove from database @@ -945,7 +943,7 @@ void AuctionHouseBotCommands(uint32 command, AuctionLocation ahMapID, uint32 col { case 0: //ahexpire { - AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(ahMapID); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMapByLocation(ahMapID); AuctionHouseObject::AuctionEntryMap::iterator itr; itr = auctionHouse->GetAuctionsBegin(); @@ -953,7 +951,7 @@ void AuctionHouseBotCommands(uint32 command, AuctionLocation ahMapID, uint32 col while (itr != auctionHouse->GetAuctionsEnd()) { if (itr->second->owner == AHBplayerGUID) - itr->second->time = sWorld.GetGameTime(); + itr->second->expire_time = sWorld.GetGameTime(); ++itr; } diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index cb72862c2c0..175db1022de 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -55,67 +55,19 @@ void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data ) SendAuctionHello(guid, unit); } -static AuctionLocation AuctioneerFactionToLocation(uint32 faction) -{ - if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) - return AUCTION_NEUTRAL; - - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(faction); - if(!u_entry) - return AUCTION_NEUTRAL; - - if(u_entry->ourMask & FACTION_MASK_ALLIANCE) - return AUCTION_ALLIANCE; - else if(u_entry->ourMask & FACTION_MASK_HORDE) - return AUCTION_HORDE; - else - return AUCTION_NEUTRAL; -} - //this void causes that auction window is opened void WorldSession::SendAuctionHello( uint64 guid, Creature* unit ) { + AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction()); + if(!ahEntry) + return; + WorldPacket data( MSG_AUCTION_HELLO, 12 ); data << (uint64) guid; - data << (uint32) AuctioneerFactionToLocation(unit->getFaction()); + data << (uint32) ahEntry->houseId; SendPacket( &data ); } -//this function inserts to WorldPacket auction's data -bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction) -{ - Item *pItem = objmgr.GetAItem(auction->item_guidlow); - if (!pItem) - { - sLog.outError("auction to item, that doesn't exist !!!!"); - return false; - } - data << (uint32) auction->Id; - data << (uint32) pItem->GetEntry(); - - for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) - { - data << (uint32) pItem->GetEnchantmentId(EnchantmentSlot(i)); - data << (uint32) pItem->GetEnchantmentDuration(EnchantmentSlot(i)); - data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i)); - } - - data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id - data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor - data << (uint32) pItem->GetCount(); //item->count - data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF - data << (uint32) 0; //Unknown - data << (uint64) auction->owner; //Auction->owner - data << (uint32) auction->startbid; //Auction->startbid (not sure if useful) - data << (uint32) ((auction->bid)? objmgr.GetAuctionOutBid(auction->bid) : 0); - //minimal outbid - data << (uint32) auction->buyout; //auction->buyout - data << (uint32) (auction->time - time(NULL)) * 1000; //time left - data << (uint64) auction->bidder; //auction->bidder current - data << (uint32) auction->bid; //current bid - return true; -} - //call this method when player bids, creates, or deletes auction void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError ) { @@ -173,12 +125,12 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED; if (oldBidder && !_player) - oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, AHBplayerGUID, newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template); + oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, AHBplayerGUID, newPrice, auction->GetAuctionOutBid(), auction->item_template); if (oldBidder && _player) - oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template); + oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); - WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); + WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); } } @@ -198,7 +150,7 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction ) std::ostringstream msgAuctionCancelledSubject; msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER; - WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); + WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); } } @@ -223,6 +175,14 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) return; } + AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction()); + if(!auctionHouseEntry) + { + sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer)) ); + return; + } + + // client send time in minutes, convert to common used sec time etime *= MINUTE; @@ -243,7 +203,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) Item *it = pl->GetItemByGuid( item ); //do not allow to sell already auctioned items - if(objmgr.GetAItem(GUID_LOPART(item))) + if(auctionmgr.GetAItem(GUID_LOPART(item))) { sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item)); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); @@ -268,12 +228,10 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) return; } - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - AuctionHouseObject * mAuctions; - mAuctions = objmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); //we have to take deposit : - uint32 deposit = objmgr.GetAuctionDeposit( location, etime, it ); + uint32 deposit = auctionmgr.GetAuctionDeposit( auctionHouseEntry, etime, it ); if ( pl->GetMoney() < deposit ) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); @@ -300,22 +258,20 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; - AH->time = time(NULL) + auction_time; + AH->expire_time = time(NULL) + auction_time; AH->deposit = deposit; - AH->location = location; + AH->auctionHouseEntry = auctionHouseEntry; - sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in location: %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, auction_time, location); - mAuctions->AddAuction(AH); + sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, auction_time, AH->GetHouseId()); + auctionHouse->AddAuction(AH); - objmgr.AddAItem(it); + auctionmgr.AddAItem(it); pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true); CharacterDatabase.BeginTransaction(); it->DeleteFromInventoryDB(); it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone - 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')", - AH->Id, AH->auctioneer, AH->item_guidlow, AH->item_template, AH->owner, AH->buyout, (uint64)AH->time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location); + AH->SaveToDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); @@ -347,12 +303,9 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); - AuctionHouseObject * mAuctions; - mAuctions = objmgr.GetAuctionsMap( location ); - - AuctionEntry *auction = mAuctions->GetAuction(auctionId); + AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if( !auction || auction->owner == pl->GetGUIDLow() ) @@ -377,7 +330,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && - price < auction->bid + objmgr.GetAuctionOutBid(auction->bid)) + price < auction->bid + auction->GetAuctionOutBid()) { //auction has already higher bid, client tests it! return; @@ -435,15 +388,15 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) auction->bidder = pl->GetGUIDLow(); auction->bid = auction->buyout; - objmgr.SendAuctionSalePendingMail( auction ); - objmgr.SendAuctionSuccessfulMail( auction ); - objmgr.SendAuctionWonMail( auction ); + auctionmgr.SendAuctionSalePendingMail( auction ); + auctionmgr.SendAuctionSuccessfulMail( auction ); + auctionmgr.SendAuctionWonMail( auction ); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); - objmgr.RemoveAItem(auction->item_guidlow); - mAuctions->RemoveAuction(auction->Id); - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); + auctionmgr.RemoveAItem(auction->item_guidlow); + auctionHouse->RemoveAuction(auction->Id); + auction->DeleteFromDB(); delete auction; } @@ -474,22 +427,19 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - - AuctionHouseObject * mAuctions; - mAuctions = objmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); - AuctionEntry *auction = mAuctions->GetAuction(auctionId); + AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if (auction && auction->owner == pl->GetGUIDLow()) { - Item *pItem = objmgr.GetAItem(auction->item_guidlow); + Item *pItem = auctionmgr.GetAItem(auction->item_guidlow); if (pItem) { if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid { - uint32 auctionCut = objmgr.GetAuctionCut( auction->location, auction->bid); + uint32 auctionCut = auction->GetAuctionCut(); if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed return; //some auctionBidderNotification would be needed, but don't know that parts.. @@ -504,7 +454,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) mi.AddItem(auction->item_guidlow, auction->item_template, pItem); // item will deleted or added to received mail list - WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); } else { @@ -525,11 +475,11 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) SendAuctionCommandResult( auction->Id, AUCTION_CANCEL, AUCTION_OK ); // Now remove the auction CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); + auction->DeleteFromDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); - objmgr.RemoveAItem( auction->item_guidlow ); - mAuctions->RemoveAuction( auction->Id ); + auctionmgr.RemoveAItem( auction->item_guidlow ); + auctionHouse->RemoveAuction( auction->Id ); delete auction; } @@ -562,8 +512,7 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) ); Player *pl = GetPlayer(); @@ -575,23 +524,15 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) --outbiddedCount; uint32 outbiddedAuctionId; recv_data >> outbiddedAuctionId; - AuctionEntry * auction = mAuctions->GetAuction( outbiddedAuctionId ); - if ( auction && SendAuctionInfo(data, auction)) + AuctionEntry * auction = auctionHouse->GetAuction( outbiddedAuctionId ); + if ( auction && auction->BuildAuctionInfo(data)) { ++totalcount; ++count; } } - for (AuctionHouseObject::AuctionEntryMap::const_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; - } - } + + auctionHouse->BuildListBidderItems(data,pl,count,totalcount); data.put<uint32>( 0, count ); // add count to placeholder data << totalcount; data << (uint32)300; //unk 2.3.0 @@ -620,25 +561,15 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - - AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); 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::const_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; - } - } + + auctionHouse->BuildListOwnerItems(data,_player,count,totalcount); data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 0; @@ -677,8 +608,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - AuctionHouseObject * mAuctions = objmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); //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); @@ -694,62 +624,11 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) wstrToLower(wsearchedname); - for (AuctionHouseObject::AuctionEntryMap::const_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 ) ) - { - std::string 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() > size_t(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; - } - } - } - } - } - } - } - } - } - } + auctionHouse->BuildListAuctionItems(data,_player, + wsearchedname, listfrom, levelmin, levelmax, usable, + auctionSlotID, auctionMainCategory, auctionSubCategory, quality, + count,totalcount); + data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 300; // unk 2.3.0 const? diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h index f82867c5742..713a9575ade 100644 --- a/src/game/AuctionHouseMgr.h +++ b/src/game/AuctionHouseMgr.h @@ -18,13 +18,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _AUCTION_HOUSE_H -#define _AUCTION_HOUSE_H +#ifndef _AUCTION_HOUSE_MGR_H +#define _AUCTION_HOUSE_MGR_H #include "SharedDefines.h" +#include "Policies/Singleton.h" + +class Item; +class Player; +class WorldPacket; #define MIN_AUCTION_TIME (12*HOUR) +//only used for bot +enum AuctionLocation +{ + AUCTION_ALLIANCE = 2, + AUCTION_HORDE = 6, + AUCTION_NEUTRAL = 7 +}; + enum AuctionError { AUCTION_OK = 0, @@ -41,29 +54,29 @@ enum AuctionAction AUCTION_PLACE_BID = 2 }; -enum AuctionLocation -{ - AUCTION_ALLIANCE = 2, - AUCTION_HORDE = 6, - AUCTION_NEUTRAL = 7 -}; - -inline bool IsValidAuctionLocation(uint32 loc) { return loc == AUCTION_ALLIANCE || loc == AUCTION_HORDE || loc == AUCTION_NEUTRAL; } - struct AuctionEntry { uint32 Id; - uint32 auctioneer; + uint32 auctioneer; // creature low guid uint32 item_guidlow; uint32 item_template; uint32 owner; uint32 startbid; //maybe useless uint32 bid; uint32 buyout; - time_t time; + time_t expire_time; uint32 bidder; uint32 deposit; //deposit can be calculated only when creating auction - AuctionLocation location; + AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc + + // helpers + uint32 GetHouseId() const { return auctionHouseEntry->houseId; } + uint32 GetHouseFaction() const { return auctionHouseEntry->faction; } + uint32 GetAuctionCut() const; + uint32 GetAuctionOutBid() const; + bool BuildAuctionInfo(WorldPacket & data) const; + void DeleteFromDB() const; + void SaveToDB() const; }; //this class is used as auctionhouse instance @@ -81,9 +94,6 @@ class AuctionHouseObject uint32 Getcount() { return AuctionsMap.size(); } - AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();} - AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();} - void AddAuction(AuctionEntry *ah) { ASSERT( ah ); @@ -101,7 +111,70 @@ class AuctionHouseObject return AuctionsMap.erase(id) ? true : false; } + // for AHBot + AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();} + AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();} + + void Update(); + + void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); + void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); + void BuildListAuctionItems(WorldPacket& data, Player* player, + std::wstring const& searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, + uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, + uint32& count, uint32& totalcount); + private: AuctionEntryMap AuctionsMap; }; + +class AuctionHouseMgr +{ + public: + AuctionHouseMgr(); + ~AuctionHouseMgr(); + + typedef UNORDERED_MAP<uint32, Item*> ItemMap; + + AuctionHouseObject* GetAuctionsMapByLocation( AuctionLocation location ); + AuctionHouseObject* GetAuctionsMap( uint32 factionTemplateId ); + + Item* GetAItem(uint32 id) + { + ItemMap::const_iterator itr = mAitems.find(id); + if (itr != mAitems.end()) + { + return itr->second; + } + return NULL; + } + + //auction messages + void SendAuctionWonMail( AuctionEntry * auction ); + void SendAuctionSalePendingMail( AuctionEntry * auction ); + void SendAuctionSuccessfulMail( AuctionEntry * auction ); + void SendAuctionExpiredMail( AuctionEntry * auction ); + static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem); + static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); + + public: + //load first auction items, because of check if item exists, when loading + void LoadAuctionItems(); + void LoadAuctions(); + + void AddAItem(Item* it); + bool RemoveAItem(uint32 id); + + void Update(); + + private: + AuctionHouseObject mHordeAuctions; + AuctionHouseObject mAllianceAuctions; + AuctionHouseObject mNeutralAuctions; + + ItemMap mAitems; +}; + +#define auctionmgr MaNGOS::Singleton<AuctionHouseMgr>::Instance() + #endif diff --git a/src/game/Makefile.am b/src/game/Makefile.am index 2a8bfd23925..2623472b2c0 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -43,6 +43,7 @@ libmangosgame_a_SOURCES = \ ArenaTeam.h \ ArenaTeamHandler.cpp \ AuctionHouseHandler.cpp \ + AuctionHouseMgr.cpp \ AuctionHouseMgr.h \ Bag.cpp \ Bag.h \ diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 7c27864bc31..a981e06bc31 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -22,6 +22,7 @@ #include "Database/DatabaseEnv.h" #include "Database/SQLStorage.h" #include "Database/SQLStorageImpl.h" +#include "Policies/SingletonImp.h" #include "Log.h" #include "MapManager.h" @@ -35,7 +36,6 @@ #include "ArenaTeam.h" #include "Transports.h" #include "ProgressBar.h" -#include "Policies/SingletonImp.h" #include "Language.h" #include "GameEvent.h" #include "Spell.h" @@ -125,9 +125,9 @@ ObjectMgr::ObjectMgr() m_hiPetNumber = 1; m_ItemTextId = 1; m_mailid = 1; - m_auctionid = 1; m_guildId = 1; m_arenaTeamId = 1; + m_auctionid = 1; mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS); mGuildBankTabPrice[0] = 100; @@ -180,8 +180,8 @@ ObjectMgr::~ObjectMgr() for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr) delete itr->second; - for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr) - delete itr->second; + //for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr) + // delete itr->second; for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) itr->second.Clear(); @@ -327,254 +327,6 @@ void ObjectMgr::RemoveArenaTeam(ArenaTeam* arenaTeam) mArenaTeamMap.erase( arenaTeam->GetId() ); } -AuctionHouseObject * ObjectMgr::GetAuctionsMap( AuctionLocation location ) -{ - switch ( location ) - { - case AUCTION_HORDE: - return & mHordeAuctions; - break; - case AUCTION_ALLIANCE: - return & mAllianceAuctions; - break; - default: //neutral - return & mNeutralAuctions; - } -} - -uint32 ObjectMgr::GetAuctionCut(AuctionLocation location, uint32 highBid) -{ - if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) - return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT)); - else - return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT)); -} - -uint32 ObjectMgr::GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem) -{ - float percentance; // in 0..1 - if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) - percentance = 0.75f; - else - percentance = 0.15f; - - percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT); - - return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) ); -} - -/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c -uint32 ObjectMgr::GetAuctionOutBid(uint32 currentBid) -{ - uint32 outbid = (currentBid / 100) * 5; - if (!outbid) - outbid = 1; - return outbid; -} - -//does not clear ram -void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction ) -{ - Item *pItem = GetAItem(auction->item_guidlow); - if(!pItem) - return; - - uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); - Player *bidder = GetPlayer(bidder_guid); - - uint32 bidder_accId = 0; - - // data for gm.log - if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) - { - uint32 bidder_security = 0; - std::string bidder_name; - if (bidder) - { - bidder_accId = bidder->GetSession()->GetAccountId(); - bidder_security = bidder->GetSession()->GetSecurity(); - bidder_name = bidder->GetName(); - } - else - { - bidder_accId = GetPlayerAccountIdByGUID(bidder_guid); - bidder_security = accmgr.GetSecurity(bidder_accId); - - if(bidder_security > SEC_PLAYER ) // not do redundant DB requests - { - if(!GetPlayerNameByGUID(bidder_guid,bidder_name)) - bidder_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN); - } - } - - if( bidder_security > SEC_PLAYER ) - { - std::string owner_name; - if(!GetPlayerNameByGUID(auction->owner,owner_name)) - owner_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN); - - uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner); - - sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", - bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid); - } - } - else if(!bidder) - bidder_accId = GetPlayerAccountIdByGUID(bidder_guid); - - // receiver exist - if(bidder || bidder_accId) - { - std::ostringstream msgAuctionWonSubject; - msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON; - - std::ostringstream msgAuctionWonBody; - msgAuctionWonBody.width(16); - msgAuctionWonBody << std::right << std::hex << auction->owner; - msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout; - sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() ); - - //prepare mail data... : - uint32 itemTextId = CreateItemText( msgAuctionWonBody.str() ); - - // set owner to bidder (to prevent delete item with sender char deleting) - // owner in `data` will set at mail receive and item extracting - CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow()); - CharacterDatabase.CommitTransaction(); - - MailItemsInfo mi; - mi.AddItem(auction->item_guidlow, auction->item_template, pItem); - - if (bidder) - bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template); - else - RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! - - // will delete item or place to receiver mail list - WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION); - } - // receiver not exist - else - { - CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow()); - RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! - delete pItem; - } -} - -void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) -{ - uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); - Player *owner = GetPlayer(owner_guid); - - // owner exist (online or offline) - if(owner || GetPlayerAccountIdByGUID(owner_guid)) - { - std::ostringstream msgAuctionSalePendingSubject; - msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING; - - std::ostringstream msgAuctionSalePendingBody; - uint32 auctionCut = GetAuctionCut(auction->location, auction->bid); - - time_t distrTime = time(NULL) + HOUR; - - msgAuctionSalePendingBody.width(16); - msgAuctionSalePendingBody << std::right << std::hex << auction->bidder; - msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout; - msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:"; - msgAuctionSalePendingBody << secsToTimeBitFields(distrTime); - - sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str()); - - uint32 itemTextId = CreateItemText( msgAuctionSalePendingBody.str() ); - - WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION); - } -} - -//call this method to send mail to auction owner, when auction is successful, it does not clear ram -void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) -{ - uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); - Player *owner = GetPlayer(owner_guid); - - uint32 owner_accId = 0; - if(!owner) - owner_accId = GetPlayerAccountIdByGUID(owner_guid); - - // owner exist - if(owner || owner_accId) - { - std::ostringstream msgAuctionSuccessfulSubject; - msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL; - - std::ostringstream auctionSuccessfulBody; - uint32 auctionCut = GetAuctionCut(auction->location, auction->bid); - - auctionSuccessfulBody.width(16); - auctionSuccessfulBody << std::right << std::hex << auction->bidder; - auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout; - auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut; - - sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str()); - - uint32 itemTextId = CreateItemText( auctionSuccessfulBody.str() ); - - uint32 profit = auction->bid + auction->deposit - auctionCut; - - if (owner) - { - //send auction owner notification, bidder must be current! - owner->GetSession()->SendAuctionOwnerNotification( auction ); - } - - WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR); - } -} - -//does not clear ram -void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction ) -{ //return an item in auction to its owner by mail - Item *pItem = GetAItem(auction->item_guidlow); - if(!pItem) - { - sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow); - return; - } - - uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); - Player *owner = GetPlayer(owner_guid); - - uint32 owner_accId = 0; - if(!owner) - owner_accId = GetPlayerAccountIdByGUID(owner_guid); - - // owner exist - if(owner || owner_accId) - { - std::ostringstream subject; - subject << auction->item_template << ":0:" << AUCTION_EXPIRED; - - if ( owner ) - owner->GetSession()->SendAuctionOwnerNotification( auction ); - else - RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! - - MailItemsInfo mi; - mi.AddItem(auction->item_guidlow, auction->item_template, pItem); - - // will delete item or place to receiver mail list - WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); - } - // owner not found - else - { - CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow()); - RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! - delete pItem; - } -} - CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id) { return sCreatureStorage.LookupEntry<CreatureInfo>(id); @@ -1603,95 +1355,6 @@ uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(const std::string& name) const return 0; } -void ObjectMgr::LoadAuctions() -{ - QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse"); - if( !result ) - { - barGoLink bar(1); - bar.step(); - sLog.outString(""); - sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); - return; - } - - Field *fields = result->Fetch(); - uint32 AuctionCount=fields[0].GetUInt32(); - delete result; - - if(!AuctionCount) - { - barGoLink bar(1); - bar.step(); - sLog.outString(""); - sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); - return; - } - - result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" ); - if( !result ) - { - barGoLink bar(1); - bar.step(); - sLog.outString(""); - sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); - return; - } - - barGoLink bar( AuctionCount ); - - AuctionEntry *aItem; - - do - { - fields = result->Fetch(); - - bar.step(); - - aItem = new AuctionEntry; - aItem->Id = fields[0].GetUInt32(); - aItem->auctioneer = fields[1].GetUInt32(); - aItem->item_guidlow = fields[2].GetUInt32(); - aItem->item_template = fields[3].GetUInt32(); - aItem->owner = fields[4].GetUInt32(); - aItem->buyout = fields[5].GetUInt32(); - aItem->time = fields[6].GetUInt32(); - aItem->bidder = fields[7].GetUInt32(); - aItem->bid = fields[8].GetUInt32(); - aItem->startbid = fields[9].GetUInt32(); - aItem->deposit = fields[10].GetUInt32(); - - uint32 loc = fields[11].GetUInt8(); - if(!IsValidAuctionLocation(loc)) - { - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id); - sLog.outError("Auction %u has wrong auction location (%u)", aItem->Id, loc); - delete aItem; - continue; - } - aItem->location = AuctionLocation(loc); - - // check if sold item exists for guid - // and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems) - if ( !GetAItem( aItem->item_guidlow ) ) - { - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id); - sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow); - delete aItem; - continue; - } - - if(aItem->location) - - GetAuctionsMap( aItem->location )->AddAuction(aItem); - - } while (result->NextRow()); - delete result; - - sLog.outString(); - sLog.outString( ">> Loaded %u auctions", AuctionCount ); -} - void ObjectMgr::LoadItemLocales() { mItemLocaleMap.clear(); // need for reload case @@ -2117,59 +1780,6 @@ void ObjectMgr::LoadItemPrototypes() } } -void ObjectMgr::LoadAuctionItems() -{ - // data needs to be at first place for Item::LoadFromDB - QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" ); - - if( !result ) - { - barGoLink bar(1); - bar.step(); - sLog.outString(""); - sLog.outString(">> Loaded 0 auction items"); - return; - } - - barGoLink bar( result->GetRowCount() ); - - uint32 count = 0; - - Field *fields; - do - { - bar.step(); - - fields = result->Fetch(); - uint32 item_guid = fields[1].GetUInt32(); - uint32 item_template = fields[2].GetUInt32(); - - ItemPrototype const *proto = GetItemPrototype(item_template); - - if(!proto) - { - sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template); - continue; - } - - Item *item = NewItemOrBag(proto); - - if(!item->LoadFromDB(item_guid,0, result)) - { - delete item; - continue; - } - AddAItem(item); - - ++count; - } - while( result->NextRow() ); - delete result; - - sLog.outString(); - sLog.outString( ">> Loaded %u auction items", count ); -} - void ObjectMgr::LoadPetLevelInfo() { // Loading levels data @@ -5651,24 +5261,24 @@ uint32 ObjectMgr::GenerateArenaTeamId() return m_arenaTeamId++; } -uint32 ObjectMgr::GenerateGuildId() +uint32 ObjectMgr::GenerateAuctionID() { - if(m_guildId>=0xFFFFFFFE) + if(m_auctionid>=0xFFFFFFFE) { - sLog.outError("Guild ids overflow!! Can't continue, shutting down server. "); + sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. "); World::StopNow(ERROR_EXIT_CODE); } - return m_guildId++; + return m_auctionid++; } -uint32 ObjectMgr::GenerateAuctionID() +uint32 ObjectMgr::GenerateGuildId() { - if(m_auctionid>=0xFFFFFFFE) + if(m_guildId>=0xFFFFFFFE) { - sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. "); + sLog.outError("Guild ids overflow!! Can't continue, shutting down server. "); World::StopNow(ERROR_EXIT_CODE); } - return m_auctionid++; + return m_guildId++; } uint32 ObjectMgr::GenerateMailID() diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index dd26e7fb37b..5637b4a3093 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -34,7 +34,6 @@ #include "ItemPrototype.h" #include "NPCHandler.h" #include "Database/DatabaseEnv.h" -#include "AuctionHouseMgr.h" #include "Mail.h" #include "Map.h" #include "ObjectAccessor.h" @@ -374,42 +373,6 @@ class ObjectMgr return sInstanceTemplate.LookupEntry<InstanceTemplate>(map); } - Item* GetAItem(uint32 id) - { - ItemMap::const_iterator itr = mAitems.find(id); - if (itr != mAitems.end()) - { - return itr->second; - } - return NULL; - } - void AddAItem(Item* it) - { - ASSERT( it ); - ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end()); - mAitems[it->GetGUIDLow()] = it; - } - bool RemoveAItem(uint32 id) - { - ItemMap::iterator i = mAitems.find(id); - if (i == mAitems.end()) - { - return false; - } - mAitems.erase(i); - return true; - } - AuctionHouseObject * GetAuctionsMap( AuctionLocation location ); - - //auction messages - void SendAuctionWonMail( AuctionEntry * auction ); - void SendAuctionSalePendingMail( AuctionEntry * auction ); - void SendAuctionSuccessfulMail( AuctionEntry * auction ); - void SendAuctionExpiredMail( AuctionEntry * auction ); - static uint32 GetAuctionCut( AuctionLocation location, uint32 highBid ); - static uint32 GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem); - static uint32 GetAuctionOutBid(uint32 currentBid); - PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const; PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const @@ -566,9 +529,6 @@ class ObjectMgr void LoadItemTexts(); void LoadPageTexts(); - //load first auction items, because of check if item exists, when loading - void LoadAuctionItems(); - void LoadAuctions(); void LoadPlayerInfo(); void LoadPetLevelInfo(); void LoadExplorationBaseXP(); @@ -601,12 +561,12 @@ class ObjectMgr void SetHighestGuids(); uint32 GenerateLowGuid(HighGuid guidhigh); + uint32 GenerateArenaTeamId(); uint32 GenerateAuctionID(); - uint32 GenerateMailID(); + uint32 GenerateGuildId(); uint32 GenerateItemTextID(); + uint32 GenerateMailID(); uint32 GeneratePetNumber(); - uint32 GenerateArenaTeamId(); - uint32 GenerateGuildId(); void LoadPlayerInfoInCache(); PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const; @@ -806,11 +766,11 @@ class ObjectMgr protected: // first free id for selected id type - uint32 m_auctionid; - uint32 m_mailid; - uint32 m_ItemTextId; uint32 m_arenaTeamId; + uint32 m_auctionid; uint32 m_guildId; + uint32 m_ItemTextId; + uint32 m_mailid; uint32 m_hiPetNumber; // first free low guid for seelcted guid type @@ -836,14 +796,9 @@ class ObjectMgr ArenaTeamMap mArenaTeamMap; ItemMap mItems; - ItemMap mAitems; ItemTextMap mItemTexts; - AuctionHouseObject mHordeAuctions; - AuctionHouseObject mAllianceAuctions; - AuctionHouseObject mNeutralAuctions; - QuestAreaTriggerMap mQuestAreaTriggerMap; TavernAreaTriggerSet mTavernAreaTriggerSet; GameObjectForQuestSet mGameObjectForQuestSet; diff --git a/src/game/PlayerDump.h b/src/game/PlayerDump.h index 206045a1be3..a33eb9edf24 100644 --- a/src/game/PlayerDump.h +++ b/src/game/PlayerDump.h @@ -20,28 +20,7 @@ #ifndef _PLAYER_DUMP_H #define _PLAYER_DUMP_H -/* -#include "Log.h" -#include "Object.h" -#include "Bag.h" -#include "Creature.h" -#include "Player.h" -#include "DynamicObject.h" -#include "GameObject.h" -#include "Corpse.h" -#include "QuestDef.h" -#include "Path.h" -#include "ItemPrototype.h" -#include "NPCHandler.h" -#include "Database/DatabaseEnv.h" -#include "AuctionHouseMgr.h" -#include "Mail.h" -#include "Map.h" -#include "ObjectAccessor.h" -#include "ObjectDefines.h" -#include "Policies/Singleton.h" -#include "Database/SQLStorage.h" -*/ + #include <string> #include <map> #include <set> diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 37a79c6adf6..9a44ee4ffac 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -810,7 +810,7 @@ class SpellMgr SpellMgr(); ~SpellMgr(); - // Accessors (const or static functions) + // Accessors (const or static functions) public: // Spell affects flag96 const*GetSpellAffect(uint16 spellId, uint8 effectId) const @@ -1073,7 +1073,7 @@ class SpellMgr return NULL; } - // Modifiers + // Modifiers public: static SpellMgr& Instance(); diff --git a/src/game/World.cpp b/src/game/World.cpp index 97938058d27..bad4eeef0c2 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -38,6 +38,7 @@ #include "World.h" #include "AccountMgr.h" #include "AchievementMgr.h" +#include "AuctionHouseMgr.h" #include "ObjectMgr.h" #include "SpellMgr.h" #include "Chat.h" @@ -609,7 +610,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Channel",false); m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Group",false); m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Guild",false); - m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",false); m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Mail",false); m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false); m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false); @@ -1317,8 +1318,8 @@ void World::SetInitialWorldSettings() ///- Load dynamic data tables from the database sLog.outString( "Loading Auctions..." ); sLog.outString(); - objmgr.LoadAuctionItems(); - objmgr.LoadAuctions(); + auctionmgr.LoadAuctionItems(); + auctionmgr.LoadAuctions(); sLog.outString( ">>> Auctions loaded" ); sLog.outString(); @@ -1579,54 +1580,8 @@ void World::Update(uint32 diff) objmgr.ReturnOrDeleteOldMails(true); } - AuctionHouseObject* AuctionMap; - for (int i = 0; i < 3; i++) - { - switch (i) - { - case 0: - AuctionMap = objmgr.GetAuctionsMap(AUCTION_HORDE); - break; - case 1: - AuctionMap = objmgr.GetAuctionsMap(AUCTION_ALLIANCE); - break; - case 2: - AuctionMap = objmgr.GetAuctionsMap(AUCTION_NEUTRAL); - break; - } - - ///- Handle expired auctions - AuctionHouseObject::AuctionEntryMap::iterator itr,next; - for (itr = AuctionMap->GetAuctionsBegin(); itr != AuctionMap->GetAuctionsEnd();itr = next) - { - next = itr; - ++next; - if (m_gameTime > (itr->second->time)) - { - ///- Either cancel the auction if there was no bidder - if (itr->second->bidder == 0) - { - objmgr.SendAuctionExpiredMail( itr->second ); - } - ///- Or perform the transaction - else - { - //we should send an "item sold" message if the seller is online - //we send the item to the winner - //we send the money to the seller - objmgr.SendAuctionSuccessfulMail( itr->second ); - objmgr.SendAuctionWonMail( itr->second ); - } - - ///- In any case clear the auction - //No SQL injection (Id is integer) - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",itr->second->Id); - objmgr.RemoveAItem(itr->second->item_guidlow); - delete itr->second; - AuctionMap->RemoveAuction(itr->first); - } - } - } + ///- Handle expired auctions + auctionmgr.Update(); } RecordTimeDiff(NULL); diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index f845fc0d1c9..d17acf29284 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -182,7 +182,6 @@ class TRINITY_DLL_SPEC WorldSession void SendAuctionCommandResult( uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0); void SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template); void SendAuctionOwnerNotification( AuctionEntry * auction ); - bool SendAuctionInfo(WorldPacket & data, AuctionEntry* auction); void SendAuctionOutbiddedMail( AuctionEntry * auction, uint32 newPrice ); void SendAuctionCancelledToBidderMail( AuctionEntry* auction ); diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 9a5605060fb..b4fb79f2dd0 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -39,6 +39,7 @@ static AreaFlagByMapID sAreaFlagByMapID; // for instances wit DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt); DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt); +DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt); DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt); DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt); @@ -193,7 +194,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 70; + const uint32 DBCFilesCount = 71; barGoLink bar( DBCFilesCount ); @@ -220,6 +221,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index dbe5e9d3bf4..6aec6db3bed 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -137,6 +137,7 @@ extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore; extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions extern DBCStorage <AreaGroupEntry> sAreaGroupStore; extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore; +extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore; extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore; extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore; extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore; diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index d041f8fa3b2..ea14a587d8e 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -514,6 +514,16 @@ struct AreaTriggerEntry float box_orientation; // 9 m_box_yaw }; +struct AuctionHouseEntry +{ + uint32 houseId; // 0 index + uint32 faction; // 1 id of faction.dbc for player factions associated with city + uint32 depositPercent; // 2 1/3 from real + uint32 cutPercent; // 3 + //char* name[16]; // 4-19 + // 20 string flag, unused +}; + struct BankBagSlotPricesEntry { uint32 ID; diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index 643e1828448..050e750cbca 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -23,6 +23,7 @@ const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix"; const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx"; const char AreaGroupEntryfmt[]="niiiiiii"; const char AreaTriggerEntryfmt[]="niffffffff"; +const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx"; const char BankBagSlotPricesEntryfmt[]="ni"; const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxx"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 048435dc33b..bc6c578f998 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7265" + #define REVISION_NR "7266" #endif // __REVISION_NR_H__ diff --git a/win/VC71/game.vcproj b/win/VC71/game.vcproj index fef56d9493f..bb608f4978e 100644 --- a/win/VC71/game.vcproj +++ b/win/VC71/game.vcproj @@ -590,6 +590,9 @@ RelativePath="..\..\src\game\ArenaTeam.h"> </File> <File + RelativePath="..\..\src\game\AuctionHouseMgr.cpp"> + </File> + <File RelativePath="..\..\src\game\AuctionHouseMgr.h"> </File> <File diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 72e0a05d168..b9a8cd113ce 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -926,6 +926,10 @@ > </File> <File + RelativePath="..\..\src\game\AuctionHouseMgr.cpp" + > + </File> + <File RelativePath="..\..\src\game\AuctionHouseMgr.h" > </File> diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index bbfbe10d6b0..27e132539a0 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -919,6 +919,10 @@ > </File> <File + RelativePath="..\..\src\game\AuctionHouseMgr.cpp" + > + </File> + <File RelativePath="..\..\src\game\AuctionHouseMgr.h" > </File> |