From 0567fb13562530be1c842736f61f740ff4674f87 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 28 Nov 2017 09:24:31 +0100 Subject: [PATCH] Core/AuctionHouse: Auction bidders Save more auction bidders than the highest bidder only --- sql/base/characters_database.sql | 27 ++++++++++- .../4.3.4/2017_11_28_00_characters.sql | 9 ++++ .../Implementation/CharacterDatabase.cpp | 3 ++ .../Implementation/CharacterDatabase.h | 3 ++ .../game/AuctionHouse/AuctionHouseMgr.cpp | 46 +++++++++++++++---- .../game/AuctionHouse/AuctionHouseMgr.h | 2 +- src/server/game/Entities/Player/Player.cpp | 2 +- .../game/Handlers/AuctionHouseHandler.cpp | 10 ++++ 8 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 sql/updates/characters/4.3.4/2017_11_28_00_characters.sql diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 017243bbb9..19eb0e0926 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -181,6 +181,30 @@ LOCK TABLES `arena_team_member` WRITE; /*!40000 ALTER TABLE `arena_team_member` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `auctionbidders` +-- + +DROP TABLE IF EXISTS `auctionbidders`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `auctionbidders` ( + `id` INT(10) unsigned NOT NULL DEFAULT '0', + `bidderguid` INT(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`,`bidderguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `auctionbidders` +-- + +LOCK TABLES `auctionbidders` WRITE; +/*!40000 ALTER TABLE `auctionbidders` DISABLE KEYS */; +/*!40000 ALTER TABLE `auctionbidders` ENABLE KEYS */; +UNLOCK TABLES; + + -- -- Table structure for table `auctionhouse` -- @@ -2848,7 +2872,8 @@ INSERT INTO `updates` VALUES ('2017_09_17_00_characters.sql','48AF8F4A6A656EF0CCEA406B4AEF71A54A5DA98E','ARCHIVED','2017-09-17 00:00:00',0), ('2017_10_16_00_characters.sql','74500AFF41A5FB2EEE24B0BFAD750C988136BA6B','ARCHIVED','2017-10-16 00:00:00',0), ('2017_11_15_00_characters.sql','22D0C3854EE6D0983CD8C43DF0AC4269386F587C','ARCHIVED','2017-11-15 00:00:00',0), -('2017_11_26_00_characters.sql','4609CDC122E0A7F27A09C2605B329A06FC7FB7C2','ARCHIVED','2017-11-27 00:00:00',0); +('2017_11_26_00_characters.sql','4609CDC122E0A7F27A09C2605B329A06FC7FB7C2','ARCHIVED','2017-11-27 00:00:00',0), +('2017_11_28_00_characters.sql','6FF1F84B8985ADFC7FF97F0BF8E53403CF13C320','ARCHIVED','2017-11-28 00:00:00',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/4.3.4/2017_11_28_00_characters.sql b/sql/updates/characters/4.3.4/2017_11_28_00_characters.sql new file mode 100644 index 0000000000..21c7192f0b --- /dev/null +++ b/sql/updates/characters/4.3.4/2017_11_28_00_characters.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS `auctionbidders`; +CREATE TABLE `auctionbidders` ( + `id` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `bidderguid` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`id`, `bidderguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `auctionbidders` (`id`, `bidderguid`) +SELECT DISTINCT `id`, `buyguid` FROM `auctionhouse` WHERE `buyguid` != 0; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index ef5cb36b5a..38e8d29ade 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -126,6 +126,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, houseid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH); PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, houseid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_AUCTION, "DELETE FROM auctionhouse WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_AUCTION_BIDDERS, "SELECT id, bidderguid FROM auctionbidders", CONNECTION_SYNCH); + PrepareStatement(CHAR_INS_AUCTION_BIDDERS, "INSERT IGNORE INTO auctionbidders (id, bidderguid) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_AUCTION_BIDDERS, "DELETE FROM auctionbidders WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_AUCTION_BID, "UPDATE auctionhouse SET buyguid = ?, lastbid = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_MAIL, "INSERT INTO mail(id, messageType, stationery, mailTemplateId, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_MAIL_BY_ID, "DELETE FROM mail WHERE id = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 2e3ea79a2e..bb3c4da5d7 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -114,6 +114,9 @@ enum CharacterDatabaseStatements CHAR_DEL_AUCTION, CHAR_UPD_AUCTION_BID, CHAR_SEL_AUCTIONS, + CHAR_SEL_AUCTION_BIDDERS, + CHAR_INS_AUCTION_BIDDERS, + CHAR_DEL_AUCTION_BIDDERS, CHAR_INS_MAIL, CHAR_DEL_MAIL_BY_ID, CHAR_INS_MAIL_ITEM, diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 9f8c514657..b5b0c3b335 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -354,21 +354,37 @@ void AuctionHouseMgr::LoadAuctions() uint32 oldMSTime = getMSTime(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONS); - PreparedQueryResult result = CharacterDatabase.Query(stmt); + PreparedQueryResult resultAuctions = CharacterDatabase.Query(stmt); - if (!result) + if (!resultAuctions) { TC_LOG_INFO("server.loading", ">> Loaded 0 auctions. DB table `auctionhouse` is empty."); return; } - uint32 count = 0; + // parse bidder list + std::unordered_map> biddersByAuction; + PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTION_BIDDERS); + uint32 countBidders = 0; + if (PreparedQueryResult resultBidders = CharacterDatabase.Query(stmt2)) + { + do + { + Field* fields = resultBidders->Fetch(); + biddersByAuction[fields[0].GetUInt32()].insert(ObjectGuid::Create(fields[1].GetUInt32())); + ++countBidders; + } + while (resultBidders->NextRow()); + } + + // parse auctions from db + uint32 countAuctions = 0; SQLTransaction trans = CharacterDatabase.BeginTransaction(); do { - Field* fields = result->Fetch(); + Field* fields = resultAuctions->Fetch(); AuctionEntry* aItem = new AuctionEntry(); if (!aItem->LoadFromDB(fields)) @@ -378,14 +394,17 @@ void AuctionHouseMgr::LoadAuctions() continue; } + auto it = biddersByAuction.find(aItem->Id); + if (it != biddersByAuction.end()) + aItem->bidders = std::move(it->second); + GetAuctionsMapByHouseId(aItem->houseId)->AddAuction(aItem); - ++count; - } while (result->NextRow()); + ++countAuctions; + } while (resultAuctions->NextRow()); CharacterDatabase.CommitTransaction(trans); - TC_LOG_INFO("server.loading", ">> Loaded %u auctions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - + TC_LOG_INFO("server.loading", ">> Loaded %u auctions with %u bidders in %u ms", countAuctions, countBidders, GetMSTimeDiffToNow(oldMSTime)); } void AuctionHouseMgr::AddAItem(Item* it) @@ -655,7 +674,7 @@ void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; - if (Aentry && Aentry->bidder == player->GetGUID().GetCounter()) + if (Aentry && Aentry->bidders.find(player->GetGUID()) != Aentry->bidders.end()) { if (itr->second->BuildAuctionInfo(data)) ++count; @@ -862,7 +881,13 @@ uint32 AuctionEntry::GetAuctionOutBid() const void AuctionEntry::DeleteFromDB(SQLTransaction& trans) const { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AUCTION); + PreparedStatement* stmt; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AUCTION); + stmt->setUInt32(0, Id); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AUCTION_BIDDERS); stmt->setUInt32(0, Id); trans->Append(stmt); } @@ -912,6 +937,7 @@ bool AuctionEntry::LoadFromDB(Field* fields) TC_LOG_ERROR("misc", "Auction %u has not a existing item : %u", Id, itemGUIDLow); return false; } + return true; } std::string AuctionEntry::BuildAuctionMailSubject(MailAuctionAnswers response) const diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 520d8074b7..1e54a6edb1 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -85,6 +85,7 @@ struct TC_GAME_API AuctionEntry ObjectGuid::LowType bidder; uint32 deposit; //deposit can be calculated only when creating auction uint32 etime; + std::unordered_set bidders; AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc // helpers @@ -161,7 +162,6 @@ class TC_GAME_API AuctionHouseMgr AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId); - AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); Item* GetAItem(ObjectGuid::LowType id) { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 14c32c957c..cca7f89496 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23213,7 +23213,7 @@ void Player::SendInitialPacketsAfterAddToMap() if (GetPlayerSharingQuest()) { if (Quest const* quest = sObjectMgr->GetQuestTemplate(GetSharedQuestID())) - PlayerTalkClass->SendQuestGiverQuestDetails(quest, GetGUID(), true); + PlayerTalkClass->SendQuestGiverQuestDetails(quest, GetGUID(), true, false); else ClearQuestSharingInfo(); } diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index a535bd2ea8..43e81eb8b3 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -537,6 +537,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) stmt->setUInt32(2, auction->Id); trans->Append(stmt); + if (auction->bidders.find(player->GetGUID()) == auction->bidders.end()) + { + // save new bidder in list, and save record to db + auction->bidders.insert(player->GetGUID()); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AUCTION_BIDDERS); + stmt->setUInt32(0, auction->Id); + stmt->setUInt32(1, auction->bidder); + trans->Append(stmt); + } + SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK); } else