aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp115
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h5
-rwxr-xr-xsrc/server/game/World/World.cpp4
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp4
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h2
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,
};