aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp123
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h11
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp7
-rw-r--r--src/server/game/World/World.cpp8
-rw-r--r--src/server/game/World/World.h1
6 files changed, 147 insertions, 4 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 768def2ff4d..20d30704c13 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -83,12 +83,23 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32
float multiplier = CalculatePct(float(entry->depositPercent), 3);
uint32 timeHr = (((time / 60) / 60) / 12);
- uint32 deposit = uint32(((multiplier * MSV * count / 3) * timeHr * 3) * sWorld->getRate(RATE_AUCTION_DEPOSIT));
+ uint32 deposit = uint32(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT));
+ float remainderbase = float(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT)) - deposit;
+
+ deposit *= timeHr * count;
+
+ int i = count;
+ while (i > 0 && (remainderbase * i) != uint32(remainderbase * i))
+ i--;
+
+ if (i)
+ deposit += remainderbase * i * timeHr;
TC_LOG_DEBUG("auctionHouse", "MSV: %u", MSV);
TC_LOG_DEBUG("auctionHouse", "Items: %u", count);
TC_LOG_DEBUG("auctionHouse", "Multiplier: %f", multiplier);
TC_LOG_DEBUG("auctionHouse", "Deposit: %u", deposit);
+ TC_LOG_DEBUG("auctionHouse", "Deposit rm: %f", remainderbase * count);
if (deposit < AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT))
return AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT);
@@ -389,6 +400,116 @@ bool AuctionHouseMgr::RemoveAItem(ObjectGuid::LowType id, bool deleteItem)
return true;
}
+void AuctionHouseMgr::PendingAuctionAdd(Player* player, AuctionEntry* aEntry)
+{
+ PlayerAuctions* thisAH;
+ auto itr = pendingAuctionMap.find(player->GetGUID());
+ if (itr != pendingAuctionMap.end())
+ thisAH = itr->second.first;
+ else
+ {
+ thisAH = new PlayerAuctions;
+ pendingAuctionMap[player->GetGUID()] = AuctionPair(thisAH, 0);
+ }
+ thisAH->push_back(aEntry);
+}
+
+uint32 AuctionHouseMgr::PendingAuctionCount(const Player* player) const
+{
+ auto const itr = pendingAuctionMap.find(player->GetGUID());
+ if (itr != pendingAuctionMap.end())
+ return itr->second.first->size();
+
+ return 0;
+}
+
+void AuctionHouseMgr::PendingAuctionProcess(Player* player)
+{
+ auto iterMap = pendingAuctionMap.find(player->GetGUID());
+ if (iterMap == pendingAuctionMap.end())
+ return;
+
+ PlayerAuctions* thisAH = iterMap->second.first;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ uint32 totalItems = 0;
+ for (auto itrAH = thisAH->begin(); itrAH != thisAH->end(); ++itrAH)
+ {
+ AuctionEntry* AH = (*itrAH);
+ totalItems += AH->itemCount;
+ }
+
+ uint32 totaldeposit = 0;
+ auto itr = (*thisAH->begin());
+
+ if (Item* item = GetAItem(itr->itemGUIDLow))
+ totaldeposit = GetAuctionDeposit(itr->auctionHouseEntry, itr->etime, item, totalItems);
+
+ uint32 depositremain = totaldeposit;
+ for (auto itr = thisAH->begin(); itr != thisAH->end(); ++itr)
+ {
+ AuctionEntry* AH = (*itr);
+
+ if (next(itr) == thisAH->end())
+ AH->deposit = depositremain;
+ else
+ {
+ AH->deposit = totaldeposit / thisAH->size();
+ depositremain -= AH->deposit;
+ }
+
+ AH->DeleteFromDB(trans);
+ AH->SaveToDB(trans);
+ }
+
+ CharacterDatabase.CommitTransaction(trans);
+ pendingAuctionMap.erase(player->GetGUID());
+ delete thisAH;
+ player->ModifyMoney(-int32(totaldeposit));
+}
+
+void AuctionHouseMgr::UpdatePendingAuctions()
+{
+ for (auto itr = pendingAuctionMap.begin(); itr != pendingAuctionMap.end();)
+ {
+ ObjectGuid playerGUID = itr->first;
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID))
+ {
+ // Check if there were auctions since last update process if not
+ if (PendingAuctionCount(player) == itr->second.second)
+ {
+ ++itr;
+ PendingAuctionProcess(player);
+ }
+ else
+ {
+ ++itr;
+ pendingAuctionMap[playerGUID].second = PendingAuctionCount(player);
+ }
+ }
+ else
+ {
+ // Expire any auctions that we couldn't get a deposit for
+ TC_LOG_WARN("auctionHouse", "Player %s was offline, unable to retrieve deposit!", playerGUID.ToString().c_str());
+ PlayerAuctions* thisAH = itr->second.first;
+ ++itr;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ for (auto AHitr = thisAH->begin(); AHitr != thisAH->end();)
+ {
+ AuctionEntry* AH = (*AHitr);
+ ++AHitr;
+ AH->expire_time = time(NULL);
+ AH->DeleteFromDB(trans);
+ AH->SaveToDB(trans);
+ }
+ CharacterDatabase.CommitTransaction(trans);
+ pendingAuctionMap.erase(playerGUID);
+ delete thisAH;
+ }
+ }
+}
+
void AuctionHouseMgr::Update()
{
mHordeAuctions.Update();
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index 45cdba361f3..1f885837a44 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -22,6 +22,7 @@
#include "Common.h"
#include "DatabaseEnv.h"
#include "DBCStructure.h"
+#include <set>
class Item;
class Player;
@@ -82,6 +83,7 @@ struct AuctionEntry
time_t expire_time;
ObjectGuid::LowType bidder;
uint32 deposit; //deposit can be calculated only when creating auction
+ uint32 etime;
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
// helpers
@@ -151,6 +153,8 @@ class AuctionHouseMgr
}
typedef std::unordered_map<ObjectGuid::LowType, Item*> ItemMap;
+ typedef std::vector<AuctionEntry*> PlayerAuctions;
+ typedef std::pair<PlayerAuctions*, uint32> AuctionPair;
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId);
@@ -184,7 +188,10 @@ class AuctionHouseMgr
void AddAItem(Item* it);
bool RemoveAItem(ObjectGuid::LowType id, bool deleteItem = false);
-
+ void PendingAuctionAdd(Player* player, AuctionEntry* aEntry);
+ uint32 PendingAuctionCount(const Player* player) const;
+ void PendingAuctionProcess(Player* player);
+ void UpdatePendingAuctions();
void Update();
private:
@@ -193,6 +200,8 @@ class AuctionHouseMgr
AuctionHouseObject mAllianceAuctions;
AuctionHouseObject mNeutralAuctions;
+ std::map<ObjectGuid, AuctionPair> pendingAuctionMap;
+
ItemMap mAitems;
};
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a8f015a8749..4804aece416 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1535,6 +1535,7 @@ void Player::Update(uint32 p_time)
//because we don't want player's ghost teleported from graveyard
if (IsHasDelayedTeleport() && IsAlive())
TeleportTo(m_teleport_dest, m_teleport_options);
+
}
void Player::setDeathState(DeathState s)
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 8ecf86680ca..a9680ff69bb 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -303,18 +303,21 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->buyout = buyout;
AH->expire_time = time(NULL) + auctionTime;
AH->deposit = deposit;
+ AH->etime = etime;
AH->auctionHouseEntry = auctionHouseEntry;
TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u",
_player->GetName().c_str(), _player->GetGUID().GetCounter(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUID().GetCounter(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(item);
auctionHouse->AddAuction(AH);
+ sAuctionMgr->PendingAuctionAdd(_player, AH);
_player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
item->DeleteFromInventoryDB(trans);
item->SaveToDB(trans);
+
AH->SaveToDB(trans);
_player->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
@@ -351,12 +354,14 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->buyout = buyout;
AH->expire_time = time(NULL) + auctionTime;
AH->deposit = deposit;
+ AH->etime = etime;
AH->auctionHouseEntry = auctionHouseEntry;
TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u",
_player->GetName().c_str(), _player->GetGUID().GetCounter(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUID().GetCounter(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(newItem);
auctionHouse->AddAuction(AH);
+ sAuctionMgr->PendingAuctionAdd(_player, AH);
for (uint32 j = 0; j < itemsCount; ++j)
{
@@ -396,8 +401,6 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
}
-
- _player->ModifyMoney(-int32(deposit));
}
//this function is called when client bids or buys out auction
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index c41caa8f955..bcfd105f3c6 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1782,6 +1782,7 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
+ m_timers[WUPDATE_AUCTIONS_PENDING].SetInterval(250);
m_timers[WUPDATE_UPTIME].SetInterval(m_int_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS);
//Update "uptime" table based on configuration entry in minutes.
m_timers[WUPDATE_CORPSES].SetInterval(20 * MINUTE * IN_MILLISECONDS);
@@ -2052,6 +2053,13 @@ void World::Update(uint32 diff)
sAuctionMgr->Update();
}
+ if (m_timers[WUPDATE_AUCTIONS_PENDING].Passed())
+ {
+ m_timers[WUPDATE_AUCTIONS_PENDING].Reset();
+
+ sAuctionMgr->UpdatePendingAuctions();
+ }
+
/// <li> Handle AHBot operations
if (m_timers[WUPDATE_AHBOT].Passed())
{
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 133ac3f2386..c76b11276cc 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -69,6 +69,7 @@ enum ShutdownExitCode
enum WorldTimers
{
WUPDATE_AUCTIONS,
+ WUPDATE_AUCTIONS_PENDING,
WUPDATE_WEATHERS,
WUPDATE_UPTIME,
WUPDATE_CORPSES,