From 2d242c86a8687da435f7b07496ab28be5a4c812d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 12 Feb 2009 03:28:54 +0300 Subject: [PATCH] [7266] Use DBC data for auction cut/deposit percents and location (auiction house id in fact). Note: `auctionhouse`.`location` field not used after this. But not removed to simplify backporting to mangos-0.12. --- src/game/AuctionHouseHandler.cpp | 87 +++++++---------- src/game/AuctionHouseMgr.cpp | 144 ++++++++++++++++++++--------- src/game/AuctionHouseMgr.h | 24 ++--- src/game/World.cpp | 2 +- src/shared/Database/DBCStores.cpp | 4 +- src/shared/Database/DBCStores.h | 1 + src/shared/Database/DBCStructure.h | 10 ++ src/shared/Database/DBCfmt.cpp | 1 + src/shared/revision_nr.h | 2 +- 9 files changed, 163 insertions(+), 112 deletions(-) diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index f9b774994..ac9ef7131 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -52,29 +52,16 @@ 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 ); } @@ -135,9 +122,9 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED; if (oldBidder) - oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), 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); } } @@ -157,7 +144,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); } } @@ -182,6 +169,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; @@ -227,12 +222,10 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) return; } - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - AuctionHouseObject * mAuctions; - mAuctions = auctionmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); //we have to take deposit : - uint32 deposit = auctionmgr.GetAuctionDeposit( location, etime, it ); + uint32 deposit = auctionmgr.GetAuctionDeposit( auctionHouseEntry, etime, it ); if ( pl->GetMoney() < deposit ) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); @@ -261,10 +254,10 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) AH->buyout = buyout; 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); auctionmgr.AddAItem(it); pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true); @@ -272,9 +265,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) 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->expire_time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location); + AH->SaveToDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); @@ -306,12 +297,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 = auctionmgr.GetAuctionsMap( location ); - - AuctionEntry *auction = mAuctions->GetAuction(auctionId); + AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if( !auction || auction->owner == pl->GetGUIDLow() ) @@ -401,8 +389,8 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); auctionmgr.RemoveAItem(auction->item_guidlow); - mAuctions->RemoveAuction(auction->Id); - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); + auctionHouse->RemoveAuction(auction->Id); + auction->DeleteFromDB(); delete auction; } @@ -433,12 +421,9 @@ void WorldSession::HandleAuctionRemoveItem( 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 = auctionmgr.GetAuctionsMap( location ); - - AuctionEntry *auction = mAuctions->GetAuction(auctionId); + AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if (auction && auction->owner == pl->GetGUIDLow()) @@ -463,7 +448,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 { @@ -484,11 +469,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(); auctionmgr.RemoveAItem( auction->item_guidlow ); - mAuctions->RemoveAuction( auction->Id ); + auctionHouse->RemoveAuction( auction->Id ); delete auction; } @@ -521,8 +506,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* auctionHouse = auctionmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) ); Player *pl = GetPlayer(); @@ -571,9 +555,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction()); - - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( location ); + AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4) ); data << (uint32) 0; // amount place holder @@ -620,8 +602,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 * auctionHouse = auctionmgr.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); diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index 8902903d8..51d003ef1 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -18,6 +18,7 @@ #include "Common.h" #include "Database/DatabaseEnv.h" +#include "Database/DBCStores.h" #include "Database/SQLStorage.h" #include "ProgressBar.h" @@ -46,32 +47,25 @@ AuctionHouseMgr::~AuctionHouseMgr() delete itr->second; } -AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap( AuctionLocation location ) +AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap( uint32 factionTemplateId ) { - switch ( location ) - { - case AUCTION_HORDE: - return & mHordeAuctions; - break; - case AUCTION_ALLIANCE: - return & mAllianceAuctions; - break; - default: //neutral - return & mNeutralAuctions; - } + // team have linked auction houses + FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId); + if(!u_entry) + return &mNeutralAuctions; + else if(u_entry->ourMask & FACTION_MASK_ALLIANCE) + return &mAllianceAuctions; + else if(u_entry->ourMask & FACTION_MASK_HORDE) + return &mHordeAuctions; + else + return &mNeutralAuctions; } -uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem) +uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, 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; + uint32 deposit = pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ); - percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT); - - return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) ); + return uint32(deposit * entry->depositPercent * 3 * sWorld.getRate(RATE_AUCTION_DEPOSIT) / 100.0f ); } //does not clear ram @@ -148,12 +142,12 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) 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); + bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), 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); + WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION); } // receiver not exist else @@ -190,7 +184,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) uint32 itemTextId = objmgr.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); + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION); } } @@ -230,7 +224,7 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) 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); + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR); } } @@ -266,7 +260,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction ) 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); + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); } // owner not found else @@ -355,7 +349,7 @@ void AuctionHouseMgr::LoadAuctions() return; } - result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" ); + result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse" ); if( !result ) { barGoLink bar(1); @@ -388,29 +382,45 @@ void AuctionHouseMgr::LoadAuctions() aItem->startbid = fields[9].GetUInt32(); aItem->deposit = fields[10].GetUInt32(); - uint32 loc = fields[11].GetUInt8(); - if(!IsValidAuctionLocation(loc)) + CreatureData const* auctioneerData = objmgr.GetCreatureData(aItem->auctioneer); + if(!auctioneerData) { - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id); - sLog.outError("Auction %u has wrong auction location (%u)", aItem->Id, loc); + aItem->DeleteFromDB(); + sLog.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer); + delete aItem; + continue; + } + + CreatureInfo const* auctioneerInfo = objmgr.GetCreatureTemplate(auctioneerData->id); + if(!auctioneerInfo) + { + aItem->DeleteFromDB(); + sLog.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem->Id, aItem->auctioneer,auctioneerData->id); + delete aItem; + continue; + } + + aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A); + if(!aItem->auctionHouseEntry) + { + aItem->DeleteFromDB(); + sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u", + aItem->Id, aItem->auctioneer,auctioneerData->id,auctioneerInfo->faction_A); 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); + aItem->DeleteFromDB(); 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); + GetAuctionsMap( auctioneerInfo->faction_A )->AddAuction(aItem); } while (result->NextRow()); delete result; @@ -444,6 +454,46 @@ void AuctionHouseMgr::Update() mNeutralAuctions.Update(); } +AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId) +{ + uint32 houseid = 1; // human auction house + + if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + { + //FIXME: found way for proper auctionhouse selection by another way + // AuctionHo use.dbc have faction field with _player_ factions associated with auction house races. + // but no easy way convert creature faction to player race faction for specific city + switch(factionTemplateId) + { + case 12: houseid = 1; break; // human + case 29: houseid = 6; break; // orc, and generic for horde + case 55: houseid = 2; break; // dwarf, and generic for alliance + case 68: houseid = 4; break; // undead + case 80: houseid = 3; break; // n-elf + case 104: houseid = 5; break; // trolls + case 120: houseid = 7; break; // booty bay, neutral + case 474: houseid = 7; break; // gadgetzan, neutral + case 855: houseid = 7; break; // everlook, neutral + case 1604: houseid = 6; break; // b-elfs, + default: // for unknown case + { + FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId); + if(!u_entry) + houseid = 7; // goblin auction house + else if(u_entry->ourMask & FACTION_MASK_ALLIANCE) + houseid = 1; // human auction house + else if(u_entry->ourMask & FACTION_MASK_HORDE) + houseid = 6; // orc auction house + else + houseid = 7; // goblin auction house + break; + } + } + } + + return sAuctionHouseStore.LookupEntry(houseid); +} + void AuctionHouseObject::Update() { time_t curTime = sWorld.GetGameTime(); @@ -471,8 +521,7 @@ void AuctionHouseObject::Update() } ///- In any case clear the auction - //No SQL injection (Id is integer) - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",itr->second->Id); + itr->second->DeleteFromDB(); auctionmgr.RemoveAItem(itr->second->item_guidlow); delete itr->second; RemoveAuction(itr->first); @@ -606,10 +655,7 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const uint32 AuctionEntry::GetAuctionCut() const { - if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) - return (uint32) (0.15f * bid * sWorld.getRate(RATE_AUCTION_CUT)); - else - return (uint32) (0.05f * bid * sWorld.getRate(RATE_AUCTION_CUT)); + return uint32(auctionHouseEntry->cutPercent * bid * sWorld.getRate(RATE_AUCTION_CUT) / 100.f); } /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c @@ -620,3 +666,17 @@ uint32 AuctionEntry::GetAuctionOutBid() const outbid = 1; return outbid; } + +void AuctionEntry::DeleteFromDB() const +{ + //No SQL injection (Id is integer) + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id); +} + +void AuctionEntry::SaveToDB() const +{ + //No SQL injection (no strings) + 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')", + Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit, GetHouseId()); +} diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h index fa1f13785..12e51cf79 100644 --- a/src/game/AuctionHouseMgr.h +++ b/src/game/AuctionHouseMgr.h @@ -44,19 +44,10 @@ 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; @@ -66,12 +57,16 @@ struct AuctionEntry 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 @@ -110,7 +105,7 @@ class AuctionHouseObject 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, + 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); @@ -127,7 +122,7 @@ class AuctionHouseMgr typedef UNORDERED_MAP ItemMap; - AuctionHouseObject * GetAuctionsMap( AuctionLocation location ); + AuctionHouseObject* GetAuctionsMap( uint32 factionTemplateId ); Item* GetAItem(uint32 id) { @@ -144,7 +139,8 @@ class AuctionHouseMgr void SendAuctionSalePendingMail( AuctionEntry * auction ); void SendAuctionSuccessfulMail( AuctionEntry * auction ); void SendAuctionExpiredMail( AuctionEntry * auction ); - static uint32 GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem); + 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 diff --git a/src/game/World.cpp b/src/game/World.cpp index d686c9667..8ef0bd812 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -617,7 +617,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); diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 4310f65f7..77c92b68e 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -37,6 +37,7 @@ static AreaFlagByMapID sAreaFlagByMapID; // for instances wit DBCStorage sAchievementStore(Achievementfmt); DBCStorage sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage sAreaTriggerStore(AreaTriggerEntryfmt); +DBCStorage sAuctionHouseStore(AuctionHouseEntryfmt); DBCStorage sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage sBattlemasterListStore(BattlemasterListEntryfmt); DBCStorage sBarberShopStyleStore(BarberShopStyleEntryfmt); @@ -191,7 +192,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 70; + const uint32 DBCFilesCount = 71; barGoLink bar( DBCFilesCount ); @@ -218,6 +219,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 b3d778fac..3156d8c85 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -135,6 +135,7 @@ extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions extern DBCStorage sAreaGroupStore; extern DBCStorage sAreaTriggerStore; +extern DBCStorage sAuctionHouseStore; extern DBCStorage sBankBagSlotPricesStore; extern DBCStorage sBarberShopStyleStore; extern DBCStorage sBattlemasterListStore; diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index b070b9acf..18f8df385 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -511,6 +511,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 1fcac5b9c..936d0e0e7 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -21,6 +21,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 048435dc3..bc6c578f9 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__