Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
BlackMarketMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AccountMgr.h"
7#include "BlackMarketMgr.h"
8#include "Common.h"
9#include "DatabaseEnv.h"
10#include "DBCStores.h"
11#include "Item.h"
12#include "Language.h"
13#include "Log.h"
14#include "ObjectMgr.h"
15#include "Player.h"
16#include "ScriptMgr.h"
17#include "World.h"
18#include "WorldPacket.h"
19#include "WorldSession.h"
20#include <vector>
21
23{
24 for (BMAuctionStore::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
25 delete itr->second;
26
27 for (BMAuctionTemplateStore::const_iterator itr = GetTemplatesBegin(); itr != GetTemplatesEnd(); ++itr)
28 delete itr->second;
29}
30
32
34{
35 BlackMarketAuctionTemplate* bmTemplate = sBlackMarketMgr->GetTemplate(GetTemplateId());
36 if (bmTemplate)
37 return bmTemplate;
38
39 return NULL;
40}
41
43{
45 stmt->setUInt32(0, GetAuctionId());
46 stmt->setUInt32(1, GetTemplateId());
47 stmt->setUInt32(2, GetStartTime());
48 stmt->setUInt32(3, GetCurrentBidder());
49 stmt->setUInt64(4, GetCurrentBid());
50 stmt->setUInt64(5, GetMinIncrement());
51 stmt->setUInt32(6, GetNumBids());
52 trans->Append(stmt);
53}
54
56{
58 stmt->setUInt32(0, GetAuctionId());
59 trans->Append(stmt);
60}
61
63{
65 stmt->setUInt32(0, GetCurrentBidder());
66 stmt->setUInt64(1, GetCurrentBid());
67 stmt->setUInt64(2, GetMinIncrement());
68 stmt->setUInt32(3, GetNumBids());
69 stmt->setUInt32(4, GetAuctionId());
70 trans->Append(stmt);
71}
72
74{
75 uint32 endTime = GetStartTime() + GetTemplate()->Duration;
76 uint32 curTime = time(NULL);
77 return (endTime >= curTime) ? endTime - curTime : 0;
78}
79
81{
82 uint32 count = 0;
83 uint32 oldMSTime = getMSTime();
84
85 if (PreparedQueryResult result = WorldDatabase.Query(WorldDatabase.GetPreparedStatement(WORLD_SEL_BLACKMARKET_TEMPLATE)))
86 {
87 do
88 {
89 Field* fields = result->Fetch();
90
91 BlackMarketAuctionTemplate* blackmarket_template = new BlackMarketAuctionTemplate();
92
93 blackmarket_template->Id = fields[0].GetUInt32();
94 blackmarket_template->MarketId = fields[1].GetUInt32();
95 blackmarket_template->SellerNPCEntry = fields[2].GetUInt32();
96 if (!sObjectMgr->GetCreatureTemplate(blackmarket_template->SellerNPCEntry))
97 {
98 SF_LOG_ERROR("sql.sql", "Table `blackmarket_template` (MarketId: %u) have data for not existing creature template (Entry: %u), ignoring", blackmarket_template->MarketId, blackmarket_template->SellerNPCEntry);
99 continue;
100 }
101 blackmarket_template->ItemEntry = fields[3].GetUInt32();
102 if (!sObjectMgr->GetItemTemplate(blackmarket_template->ItemEntry))
103 {
104 SF_LOG_ERROR("sql.sql", "Table `blackmarket_template` (MarketId: %u) have data for not existing item template (Entry: %u), ignoring.", blackmarket_template->MarketId, blackmarket_template->ItemEntry);
105 continue;
106 }
107 blackmarket_template->Quantity = fields[4].GetUInt32();
108 if (!blackmarket_template->Quantity)
109 {
110 SF_LOG_ERROR("sql.sql", "Table `blackmarket_template` (MarketId: %u) have amount == 0 for (ItemEntry : %u) in `blackmarket_template` table, ignoring.", blackmarket_template->MarketId, blackmarket_template->ItemEntry);
111 continue;
112 }
113 blackmarket_template->MinBid = fields[5].GetUInt32();
114 blackmarket_template->Duration = fields[6].GetUInt32();
115 blackmarket_template->Chance = fields[7].GetFloat();
116
117 _templates[blackmarket_template->Id] = blackmarket_template;
118
119 ++count;
120 } while (result->NextRow());
121 }
122
123 SF_LOG_INFO("server.loading", ">> Loaded %u BlackMarket templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
124}
126{
127 uint32 count = 0;
128 uint32 oldMSTime = getMSTime();
129
131 {
132 SQLTransaction trans = CharacterDatabase.BeginTransaction();
133 do
134 {
135 Field* fields = result->Fetch();
136
137 uint32 auctionId = fields[0].GetUInt32();
138 uint32 templateId = fields[1].GetUInt32();
139 uint32 startTime = fields[2].GetUInt32();
140 uint32 currentBidder = fields[3].GetUInt32();
141 uint64 currentBid = fields[4].GetUInt64();
142 uint64 minIncrement = fields[5].GetUInt64();
143 uint32 numBids = fields[6].GetUInt32();
144
145 BlackMarketAuction* auction = new BlackMarketAuction(auctionId, templateId, startTime, currentBidder, currentBid, minIncrement, numBids);
146
147 if (auction->GetTemplate() == NULL)
148 {
149 auction->DeleteFromDB(trans);
150 delete auction;
151 continue;
152 }
153
154 _auctions[auction->GetAuctionId()] = auction;
155
156 ++count;
157 } while (result->NextRow());
158
159 CharacterDatabase.CommitTransaction(trans);
160 }
161
162 SF_LOG_INFO("server.loading", ">> Loaded %u BlackMarket Auctions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
163}
164
166{
167 SQLTransaction trans = CharacterDatabase.BeginTransaction();
168
169 // Delete expired auctions
170 for (BMAuctionStore::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd();)
171 {
172 BlackMarketAuction* auction = itr->second;
173 if (auction->IsExpired())
174 {
175 if (auction->GetCurrentBidder())
176 SendAuctionWon(auction, trans);
177
178 auction->DeleteFromDB(trans);
179 _auctions.erase((itr++)->first);
180 }
181 else
182 ++itr;
183 }
184
185 // Add New Auctions
187 if (add > 0)
188 CreateAuctions(add, trans);
189
190 CharacterDatabase.CommitTransaction(trans);
191}
192
194{
195 uint32 newId = 1;
196 while (GetAuction(newId)) { ++newId; }
197 return newId;
198}
199
201{
202 if (_templates.empty())
203 return;
204
205 for (uint32 i = 0; i < number; ++i)
206 {
207 // Select a template
208 std::vector<uint32> templateList;
209 uint32 rand = std::rand() % 100 + 1;
210
211 for (BMAuctionTemplateStore::const_iterator itr = GetTemplatesBegin(); itr != GetTemplatesEnd(); ++itr)
212 {
213 if (itr->second->Chance >= rand)
214 templateList.push_back(itr->first);
215 }
216
217 for (BMAuctionStore::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
218 templateList.erase(std::remove(templateList.begin(), templateList.end(), itr->second->GetTemplateId()), templateList.end());
219
220 if (templateList.empty())
221 continue;
222
223 BlackMarketAuctionTemplate* selTemplate = GetTemplate(templateList[std::rand() % templateList.size()]);
224
225 if (!selTemplate)
226 continue;
227
229
230 uint32 minIncrement = selTemplate->MinBid * 0.05f;
231
233 auction->SetAuctionId(GetFreeAuctionId());
234 auction->SetCurrentBid(selTemplate->MinBid);
235 auction->SetCurrentBidder(0);
236 auction->SetNumBids(0);
237 auction->SetMinIncrement(minIncrement);
238 auction->SetStartTime(startTime);
239 auction->SetTemplateId(selTemplate->Id);
240
241 _auctions[auction->GetAuctionId()] = auction;
242
243 auction->SaveToDB(trans);
244 }
245}
246
248{
249 uint32 count = 0;
250
251 data << uint32(1); // LastUpdateID
252 data.WriteBits(count, 18); // ItemCount Placeholder
253
254 for (BMAuctionStore::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
255 {
256 BlackMarketAuction* auction = itr->second;
257 if (!auction->IsActive())
258 continue;
259
260 data.WriteBit((guidLow == auction->GetCurrentBidder()));
261
262 ++count;
263 }
264
265 data.FlushBits();
266
267 for (BMAuctionStore::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
268 {
269 BlackMarketAuction* auction = itr->second;
270 if (!auction->IsActive())
271 continue;
272
273 data << uint32(auction->GetTemplate()->MarketId); // MarketId
274 data << uint32(auction->GetTemplate()->Quantity); // Quantity
275 data << uint32(auction->GetAuctionId()); // AuctionId
276 data << uint32(auction->GetNumBids()); // NumBids
277 data << uint32(auction->GetTemplate()->ItemEntry); // ItemEntry
278 data << uint64(auction->GetTemplate()->MinBid); // MinBid
279 data << uint64(auction->GetCurrentBid()); // CurrentBid
280 data << uint64(auction->GetMinIncrement()); // MinIncrement
281 data << uint32(auction->GetTemplate()->SellerNPCEntry); // SellerNPC
282 data << uint32(auction->TimeLeft()); // SecondsRemaining
283 }
284
285 data.PutBits<uint32>(32, count, 18);
286
287 SF_LOG_DEBUG("network", ">> Sent %u Black Market Auctions", count);
288}
289
290void BlackMarketMgr::UpdateAuction(BlackMarketAuction* auction, uint64 newPrice, uint64 requiredIncrement, Player* newBidder)
291{
292 uint64 currentBid = newPrice + requiredIncrement;
293 uint64 minIncrement = currentBid * 0.05f;
294 SQLTransaction trans = CharacterDatabase.BeginTransaction();
295
296 if (auction->GetCurrentBidder())
297 SendAuctionOutbidded(auction, trans);
298
299 auction->SetCurrentBid(currentBid);
300 auction->SetCurrentBidder(newBidder->GetGUIDLow());
301 auction->SetMinIncrement(minIncrement);
302 auction->SetNumBids(auction->GetNumBids() + 1);
303
304 auction->UpdateToDB(trans);
305
306 CharacterDatabase.CommitTransaction(trans);
307}
308
310{
311 for (BMAuctionTemplateStore::const_iterator itr = _templates.begin(); itr != _templates.end(); ++itr)
312 if (itr->second->Id == templateId)
313 return itr->second;
314
315 SF_LOG_DEBUG("blackMarket", "BlackMarketMgr::GetTemplate: [%u] not found!", templateId);
316 return NULL;
317}
318
320{
321 for (BMAuctionStore::const_iterator itr = _auctions.begin(); itr != _auctions.end(); ++itr)
322 if (itr->second->GetAuctionId() == auctionId)
323 return itr->second;
324
325 SF_LOG_DEBUG("blackMarket", "BlackMarketMgr::GetAuction: [%u] not found!", auctionId);
326 return NULL;
327}
328
330{
331 std::ostringstream strm;
332 strm << GetTemplate()->ItemEntry << ":0:" << uint8(response) << ':' << GetAuctionId() << ':' << GetTemplate()->Quantity;
333 return strm.str();
334}
335
337{
338 std::ostringstream strm;
339 strm.width(16);
340 strm << std::right << std::hex << MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER); // HIGHGUID_PLAYER always present, even for empty guids
341 strm << std::dec << ':' << GetCurrentBid() << ':' << 0;
342 strm << ':' << 0 << ':' << 0;
343 return strm.str();
344}
345
347{
348 uint64 bidder_guid = MAKE_NEW_GUID(auction->GetCurrentBidder(), 0, HIGHGUID_PLAYER);
349 Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
350 uint32 bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid);
351
352 if (bidder || bidder_accId)
353 {
354 if (bidder)
355 {
357
358 data << uint32(auction->GetTemplate()->ItemEntry);
359 data << uint32(1);
360 data << uint32(1);
361 bidder->GetSession()->SendPacket(&data);
362 }
363
365 .AddMoney(auction->GetCurrentBid())
366 .SendMailTo(trans, MailReceiver(bidder, auction->GetCurrentBidder()), auction, MAIL_CHECK_MASK_COPIED);
367 }
368}
369
371{
372 uint64 bidder_guid = MAKE_NEW_GUID(auction->GetCurrentBidder(), 0, HIGHGUID_PLAYER);
373 Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
374 uint32 bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid);
375
376 if (bidder || bidder_accId)
377 {
378 if (bidder)
379 {
381 data << uint32(1); // 6 - might be OK - 6 (win msg recvd)
382 data << uint32(auction->GetTemplate()->ItemEntry); // 4 - ItemEntry
383 data << uint32(1); // 5 - might be OK - 5 (win msg recvd)
384
385 bidder->GetSession()->SendPacket(&data);
386 }
387
388 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(auction->GetTemplate()->ItemEntry);
389 if (!itemTemplate)
390 return;
391
392 Item* pItem = Item::CreateItem(auction->GetTemplate()->ItemEntry, auction->GetTemplate()->Quantity, bidder);
393
395 if (pItem)
396 {
397 pItem->SaveToDB(trans);
398 draft.AddItem(pItem);
399 }
400 draft.SendMailTo(trans, MailReceiver(bidder, auction->GetCurrentBidder()), MailSender(auction), MAIL_CHECK_MASK_COPIED);
401 CharacterDatabase.CommitTransaction(trans);
402 }
403}
BMMailAuctionAnswers
#define sBlackMarketMgr
struct BlackMarketAuction BlackMarketAuction
struct BlackMarketAuctionTemplate BlackMarketAuctionTemplate
@ CHAR_DEL_BLACKMARKET_AUCTION
@ CHAR_UPD_BLACKMARKET_AUCTION
@ CHAR_SEL_BLACKMARKET_AUCTIONS
@ CHAR_INS_BLACKMARKET_AUCTION
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
Definition Mail.h:37
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ WORLD_SEL_BLACKMARKET_TEMPLATE
void SendAuctionWon(BlackMarketAuction *auction, SQLTransaction &trans)
void SendAuctionOutbidded(BlackMarketAuction *auction, SQLTransaction &trans)
BlackMarketAuction * GetAuction(uint32 auctionId) const
BMAuctionStore::iterator GetAuctionsEnd()
uint32 GetFreeAuctionId()
BMAuctionTemplateStore _templates
void UpdateAuction(BlackMarketAuction *auction, uint64 newPrice, uint64 requiredIncrement, Player *newBidder)
BMAuctionStore _auctions
void CreateAuctions(uint32 number, SQLTransaction &trans)
BMAuctionTemplateStore::iterator GetTemplatesBegin()
void LoadBlackMarketAuctions()
void LoadBlackMarketTemplates()
BMAuctionStore::iterator GetAuctionsBegin()
void BuildBlackMarketRequestItemsResult(WorldPacket &data, uint32 guidLow)
BlackMarketAuctionTemplate * GetTemplate(uint32 templateId) const
BMAuctionTemplateStore::iterator GetTemplatesEnd()
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void PutBits(size_t pos, T value, uint32 bitCount)
Definition ByteBuffer.h:283
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void FlushBits()
Definition ByteBuffer.h:154
Definition Field.h:16
uint64 GetUInt64() const
Definition Field.h:141
float GetFloat() const
Definition Field.h:177
uint32 GetUInt32() const
Definition Field.h:105
Definition Item.h:202
virtual void SaveToDB(SQLTransaction &trans)
Definition Item.cpp:305
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=NULL)
Definition Item.cpp:1012
void SendMailTo(SQLTransaction &trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:162
MailDraft & AddItem(Item *item)
Definition Mail.cpp:70
MailDraft & AddMoney(uint64 money)
Definition Mail.h:126
static Player * FindPlayer(uint64)
uint32 GetGUIDLow() const
Definition Object.h:120
WorldSession * GetSession() const
Definition Player.h:2417
void setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
@ SMSG_BLACKMARKET_OUT_BID
Definition Opcodes.h:567
@ SMSG_BLACKMARKET_BID_WON
Definition Opcodes.h:565
#define sWorld
Definition World.h:910
@ CONFIG_BLACK_MARKET_AUCTION_DELAY_MOD
Definition World.h:366
@ CONFIG_BLACK_MARKET_MAX_AUCTIONS
Definition World.h:364
@ CONFIG_BLACK_MARKET_AUCTION_DELAY
Definition World.h:365
void SetStartTime(uint32 startTime)
uint32 GetStartTime() const
void UpdateToDB(SQLTransaction &trans)
void SaveToDB(SQLTransaction &trans)
uint32 GetTemplateId() const
uint32 GetCurrentBidder() const
bool IsActive() const
void SetCurrentBid(uint64 currentBid)
uint32 GetNumBids() const
std::string BuildAuctionMailBody(uint32 lowGuid)
void SetNumBids(uint32 numBids)
uint64 GetCurrentBid() const
void SetCurrentBidder(uint32 currentBidder)
void SetTemplateId(uint32 templateId)
BlackMarketAuctionTemplate * GetTemplate() const
uint32 GetAuctionId() const
bool IsExpired() const
void DeleteFromDB(SQLTransaction &trans)
void SetMinIncrement(uint64 minIncrement)
std::string BuildAuctionMailSubject(BMMailAuctionAnswers response)
uint64 GetMinIncrement() const
void SetAuctionId(uint32 auctionId)