diff options
5 files changed, 130 insertions, 0 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index ffffeaeac43..566133f63fd 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -771,3 +771,118 @@ bool AuctionEntry::LoadFromDB(Field* fields) } return true; } + +void AuctionHouseMgr::DeleteExpiredAuctionsAtStartup() +{ + // Deletes expired auctions. Should be called at server start before loading auctions. + + // DO NOT USE after auctions are already loaded since this deletes from the DB + // and assumes the auctions HAVE NOT been loaded into a list or AuctionEntryMap yet + + uint32 oldMSTime = getMSTime(); + uint32 expirecount = 0; + time_t curTime = sWorld->GetGameTime(); + + // Query the DB to see if there are any expired auctions + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_EXPIRED_AUCTIONS); + stmt->setUInt32(0, (uint32)curTime+60); + PreparedQueryResult expAuctions = CharacterDatabase.Query(stmt); + + if (!expAuctions) + { + sLog->outString(">> No expired auctions to delete"); + sLog->outString(); + return; + } + + do + { + Field* fields = expAuctions->Fetch(); + + AuctionEntry *auction = new AuctionEntry(); + + // Can't use LoadFromDB() because it assumes the auction map is loaded + if (!auction->LoadFromFieldList(fields)) + { + // For some reason the record in the DB is broken (possibly corrupt + // faction info). Delete the object and move on. + delete auction; + continue; + } + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + if (auction->bidder==0) + { + // Cancel the auction, there was no bidder + sAuctionMgr->SendAuctionExpiredMail(auction, trans); + } + else + { + // Send the item to the winner and money to seller + sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); + sAuctionMgr->SendAuctionWonMail(auction, trans); + } + + // Call the appropriate AuctionHouseObject script + // ** Do we need to do this while core is still loading? ** + sScriptMgr->OnAuctionExpire(GetAuctionsMap(auction->factionTemplateId), auction); + + // Delete the auction from the DB + auction->DeleteFromDB(trans); + CharacterDatabase.CommitTransaction(trans); + + // Release memory + delete auction; + ++expirecount; + + } while (expAuctions->NextRow()); + + sLog->outString(">> Deleted %u expired auctions in %u ms", expirecount, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); + +} + +bool AuctionEntry::LoadFromFieldList(Field* fields) +{ + // Loads an AuctionEntry item from a field list. Unlike "LoadFromDB()", this one + // does not require the AuctionEntryMap to have been loaded with items. It simply + // acts as a wrapper to fill out an AuctionEntry struct from a field list + + Id = fields[0].GetUInt32(); + auctioneer = fields[1].GetUInt32(); + item_guidlow = fields[2].GetUInt32(); + item_template = fields[3].GetUInt32(); + owner = fields[4].GetUInt32(); + buyout = fields[5].GetUInt32(); + expire_time = fields[6].GetUInt32(); + bidder = fields[7].GetUInt32(); + bid = fields[8].GetUInt32(); + startbid = fields[9].GetUInt32(); + deposit = fields[10].GetUInt32(); + + CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(auctioneer); + if (!auctioneerData) + { + sLog->outError("AuctionEntry::LoadFromFieldList() - Auction %u has not a existing auctioneer (GUID : %u)", Id, auctioneer); + return false; + } + + CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id); + if (!auctioneerInfo) + { + sLog->outError("AuctionEntry::LoadFromFieldList() - Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", Id, auctioneer, auctioneerData->id); + return false; + } + + factionTemplateId = auctioneerInfo->faction_A; + auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(factionTemplateId); + + if (!auctionHouseEntry) + { + sLog->outError("AuctionEntry::LoadFromFieldList() - Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u", Id, auctioneer, auctioneerData->id, factionTemplateId); + return false; + } + + return true; +}
\ No newline at end of file diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index bf9edbce38b..6cfc6d07e0b 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -72,6 +72,8 @@ struct AuctionEntry void DeleteFromDB(SQLTransaction& trans) const; void SaveToDB(SQLTransaction& trans) const; bool LoadFromDB(Field* fields); + bool LoadFromFieldList(Field* fields); + }; //this class is used as auctionhouse instance @@ -154,6 +156,9 @@ class AuctionHouseMgr public: + // Used primarily at server start to avoid loading a list of expired auctions + void DeleteExpiredAuctionsAtStartup(); + //load first auction items, because of check if item exists, when loading void LoadAuctionItems(); void LoadAuctions(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e2942495cb3..d28bd71963e 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1505,6 +1505,10 @@ void World::SetInitialWorldSettings() sLog->outString("Loading Completed Achievements..."); sAchievementMgr->LoadCompletedAchievements(); + // Delete expired auctions before loading + sLog->outString("Deleting expired auctions..."); + sAuctionMgr->DeleteExpiredAuctionsAtStartup(); + ///- Load dynamic data tables from the database sLog->outString("Loading Item Auctions..."); sAuctionMgr->LoadAuctionItems(); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index bb01c4ad138..5a05e53f97a 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -335,4 +335,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_ADD_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_ADD_GM_SUBSURVEY, "INSERT INTO gm_subsurveys (surveyId, subsurveyId, rank, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_ADD_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + + // For loading and deleting expired auctions at startup + PREPARE_STATEMENT(CHAR_LOAD_EXPIRED_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ah.time <= ?", CONNECTION_SYNCH) + } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 2d9ebd93a3f..372bbfe62ee 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -284,6 +284,8 @@ enum CharacterDatabaseStatements CHAR_ADD_GM_SUBSURVEY, CHAR_ADD_LAG_REPORT, + CHAR_LOAD_EXPIRED_AUCTIONS, + MAX_CHARACTERDATABASE_STATEMENTS, }; |