📄 stall network.cpp.svn-base
字号:
#include "StdAfx.h"
void Stall::DeleteFromDB()
{
CharacterDatabase.WaitExecute("DELETE FROM STALL WHERE StallId = %u", Id);
}
void Stall::SaveToDB(uint32 STALLId)
{
CharacterDatabase.Execute("INSERT INTO STALL VALUES(%u, %u, "I64FMTD", %u, %u, %u, %u, %u, %u)",
Id, STALLId, pItem->GetGUID(), Owner, BuyoutPrice, ExpiryTime, HighestBidder, HighestBid,
DepositAmount);
}
void Stall::UpdateInDB()
{
CharacterDatabase.Execute("UPDATE STALL SET bidder = %u WHERE StallId = %u", HighestBidder, Id);
CharacterDatabase.Execute("UPDATE STALL SET bid = %u WHERE StallId = %u", HighestBid, Id);
}
STALL::STALL(uint32 ID)
{
dbc = dbcSTALL.LookupEntry(ID);
assert(dbc);
cut_percent = float( float(dbc->tax) / 100.0f );
deposit_percent = float( float(dbc->fee ) / 100.0f );
}
STALL::~STALL()
{
HM_NAMESPACE::hash_map<uint32, Stall*>::iterator itr = STALL.begin();
for(; itr != STALL.end(); ++itr)
delete itr->second;
}
void STALL::QueueDeletion(Stall * auct, uint32 Reason)
{
if(auct->Deleted)
return;
auct->Deleted = true;
auct->DeletedReason = Reason;
removalLock.Acquire();
removalList.push_back(auct);
removalLock.Release();
}
void STALL::UpdateDeletionQueue()
{
removalLock.Acquire();
Stall * auct;
list<Stall*>::iterator it = removalList.begin();
for(; it != removalList.end(); ++it)
{
auct = *it;
assert(auct->Deleted);
RemoveStall(auct);
}
removalList.clear();
removalLock.Release();
}
void STALL::UpdateSTALL()
{
StallLock.AcquireReadLock();
removalLock.Acquire();
uint32 t = (uint32)UNIXTIME;
HM_NAMESPACE::hash_map<uint32, Stall*>::iterator itr = STALL.begin();
Stall * auct;
for(; itr != STALL.end();)
{
auct = itr->second;
++itr;
if(t >= auct->ExpiryTime)
{
if(auct->HighestBidder == 0)
auct->DeletedReason = Stall_REMOVE_EXPIRED;
else
auct->DeletedReason = Stall_REMOVE_WON;
auct->Deleted = true;
removalList.push_back(auct);
}
}
removalLock.Release();
StallLock.ReleaseReadLock();
}
void STALL::AddStall(Stall * auct)
{
// add to the map
StallLock.AcquireWriteLock();
STALL.insert( HM_NAMESPACE::hash_map<uint32, Stall*>::value_type( auct->Id , auct ) );
StallLock.ReleaseWriteLock();
// add the item
itemLock.AcquireWriteLock();
StalledItems.insert( HM_NAMESPACE::hash_map<uint64, Item*>::value_type( auct->pItem->GetGUID(), auct->pItem ) );
itemLock.ReleaseWriteLock();
Log.Debug("STALL", "%u: Add Stall %u, expire@ %u.", dbc->id, auct->Id, auct->ExpiryTime);
}
Stall * STALL::GetStall(uint32 Id)
{
Stall * ret;
HM_NAMESPACE::hash_map<uint32, Stall*>::iterator itr;
StallLock.AcquireReadLock();
itr = STALL.find(Id);
ret = (itr == STALL.end()) ? 0 : itr->second;
StallLock.ReleaseReadLock();
return ret;
}
void STALL::RemoveStall(Stall * auct)
{
Log.Debug("STALL", "%u: Removing Stall %u, reason %u.", dbc->id, auct->Id, auct->DeletedReason);
char subject[100];
char body[200];
switch(auct->DeletedReason)
{
case Stall_REMOVE_EXPIRED:
{
// ItemEntry:0:3
snprintf(subject, 100, "%u:0:3", (unsigned int)auct->pItem->GetEntry());
// Stall expired, resend item, no money to owner.
sMailSystem.SendAutomatedMessage(Stall, dbc->id, auct->Owner, subject, "", 0, 0, auct->pItem->GetGUID(), 62);
}break;
case Stall_REMOVE_WON:
{
// ItemEntry:0:1
snprintf(subject, 100, "%u:0:1", (unsigned int)auct->pItem->GetEntry());
// <owner player guid>:bid:buyout
snprintf(body, 200, "%X:%u:%u", (unsigned int)auct->Owner, (unsigned int)auct->HighestBid, (unsigned int)auct->BuyoutPrice);
// Stall won by highest bidder. He gets the item.
sMailSystem.SendAutomatedMessage(Stall, dbc->id, auct->HighestBidder, subject, body, 0, 0, auct->pItem->GetGUID(), 62);
// Send a mail to the owner with his cut of the price.
uint32 Stall_cut = FL2UINT(float(cut_percent * float(auct->HighestBid)));
int32 amount = auct->HighestBid - Stall_cut + auct->DepositAmount;
if(amount < 0)
amount = 0;
// ItemEntry:0:2
snprintf(subject, 100, "%u:0:2", (unsigned int)auct->pItem->GetEntry());
// <hex player guid>:bid:0:deposit:cut
if(auct->HighestBid == auct->BuyoutPrice) // Buyout
snprintf(body, 200, "%X:%u:%u:%u:%u", (unsigned int)auct->HighestBidder, (unsigned int)auct->HighestBid, (unsigned int)auct->BuyoutPrice, (unsigned int)auct->DepositAmount, (unsigned int)Stall_cut);
else
snprintf(body, 200, "%X:%u:0:%u:%u", (unsigned int)auct->HighestBidder, (unsigned int)auct->HighestBid, (unsigned int)auct->DepositAmount, (unsigned int)Stall_cut);
// send message away.
sMailSystem.SendAutomatedMessage(Stall, dbc->id, auct->Owner, subject, body, amount, 0, 0, 62);
}break;
case Stall_REMOVE_CANCELLED:
{
snprintf(subject, 100, "%u:0:5", (unsigned int)auct->pItem->GetEntry());
uint32 cut = uint32(float(cut_percent * auct->HighestBid));
Player * plr = objmgr.GetPlayer(auct->Owner);
if(cut && plr && plr->GetUInt32Value(PLAYER_FIELD_COINAGE) >= cut)
plr->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -((int32)cut));
sMailSystem.SendAutomatedMessage(Stall, GetID(), auct->Owner, subject, "", 0, 0, auct->pItem->GetGUID(), 62);
// return bidders money
if(auct->HighestBidder)
{
sMailSystem.SendAutomatedMessage(Stall, GetID(), auct->HighestBidder, subject, "", auct->HighestBid,
0, 0, 62);
}
}break;
}
// Remove the Stall from the hashmap.
StallLock.AcquireWriteLock();
itemLock.AcquireWriteLock();
STALL.erase(auct->Id);
StalledItems.erase(auct->pItem->GetGUID());
StallLock.ReleaseWriteLock();
itemLock.ReleaseWriteLock();
// Destroy the item from memory (it still remains in the db)
delete auct->pItem;
// Finally destroy the Stall instance.
auct->DeleteFromDB();
delete auct;
}
void WorldSession::HandleStallListBidderItems( WorldPacket & recv_data )
{
if(!_player->IsInWorld())
return;
uint64 guid;
recv_data >> guid;
Creature * pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
if(!pCreature || !pCreature->STALL)
return;
pCreature->STALL->SendBidListPacket(_player, &recv_data);
}
void Stall::AddToPacket(WorldPacket & data)
{
data << Id;
data << pItem->GetEntry();
for (uint32 i = 0; i < 6; i++)
{
data << pItem->GetUInt32Value(ITEM_FIELD_ENCHANTMENT + (3 * i)); // Enchantment ID
data << uint32(pItem->GetEnchantmentApplytime(i)); // Unknown / maybe ApplyTime
data << pItem->GetUInt32Value(ITEM_FIELD_SPELL_CHARGES + i); // Charges
}
data << pItem->GetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); // -ItemRandomSuffix / random property : If the value is negative its ItemRandomSuffix if its possitive its RandomItemProperty
data << pItem->GetUInt32Value(ITEM_FIELD_PROPERTY_SEED); // when ItemRandomSuffix is used this is the modifier
/******************** ItemRandomSuffix***************************
* For what I have seen ItemRandomSuffix is like RandomItemProperty
* The only difference is has is that it has a modifier.
* That is the result of jewelcrafting, the effect is that the
* enchantment is variable. That means that a enchantment can be +1 and
* with more Jem's +12 or so.
* Decription for lookup: You get the enchantmentSuffixID and search the
* DBC for the last 1 - 3 value's(depending on the enchantment).
* That value is what I call EnchantmentValue. You guys might find a
* better name but for now its good enough. The formula to calculate
* The ingame "GAIN" is:
* (Modifier / 10000) * enchantmentvalue = EnchantmentGain;
*/
data << pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT); // Amount
data << uint32(0); // Unknown
data << uint32(0); // Unknown
data << uint64(Owner); // Owner guid
data << HighestBid; // Current prize
// hehe I know its evil, this creates a nice trough put of money
data << uint32(50); // Next bid value modifier, like current bid + this value
data << BuyoutPrice; // Buyout
data << uint32((ExpiryTime - UNIXTIME) * 1000); // Time left
data << uint64(HighestBidder); // Last bidder
data << HighestBid; // The bid of the last bidder
}
void STALL::SendBidListPacket(Player * plr, WorldPacket * packet)
{
uint32 count = 0;
WorldPacket data(SMSG_Stall_BIDDER_LIST_RESULT, 1024);
data << uint32(0); // Placeholder
Stall * auct;
StallLock.AcquireReadLock();
HM_NAMESPACE::hash_map<uint32, Stall*>::iterator itr = STALL.begin();
for(; itr != STALL.end(); ++itr)
{
auct = itr->second;
if(auct->HighestBidder == plr->GetGUID())
{
if(auct->Deleted) continue;
auct->AddToPacket(data);
(*(uint32*)&data.contents()[0])++;
++count;
}
}
#ifdef USING_BIG_ENDIAN
swap32((uint32*)&data.contents()[0]);
#endif
data << count;
StallLock.ReleaseReadLock();
plr->GetSession()->SendPacket(&data);
}
void STALL::SendOwnerListPacket(Player * plr, WorldPacket * packet)
{
uint32 count = 0;
WorldPacket data(SMSG_Stall_OWNER_LIST_RESULT, 1024);
data << uint32(0); // Placeholder
Stall * auct;
StallLock.AcquireReadLock();
HM_NAMESPACE::hash_map<uint32, Stall*>::iterator itr = STALL.begin();
for(; itr != STALL.end(); ++itr)
{
auct = itr->second;
if(auct->Owner == plr->GetGUID())
{
if(auct->Deleted) continue;
auct->AddToPacket(data);
(*(uint32*)&data.contents()[0])++;
++count;
}
}
data << count;
#ifdef USING_BIG_ENDIAN
swap32((uint32*)&data.contents()[0]);
#endif
StallLock.ReleaseReadLock();
plr->GetSession()->SendPacket(&data);
}
void STALL::SendStallNotificationPacket(Player * plr, Stall * auct)
{
WorldPacket data(SMSG_Stall_BIDDER_NOTIFICATION, 32);
data << GetID();
data << auct->Id;
data << uint64(auct->HighestBidder);
data << uint32(0);
data << uint32(0);
data << auct->pItem->GetEntry();
data << uint32(0);
plr->GetSession()->SendPacket(&data);
}
void WorldSession::HandleStallPlaceBid( WorldPacket & recv_data )
{
if(!_player->IsInWorld())
return;
uint64 guid;
recv_data >> guid;
uint32 Stall_id, price;
recv_data >> Stall_id >> price;
Creature * pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
if(!pCreature || !pCreature->STALL)
return;
// Find Item
STALL * ah = pCreature->STALL;
Stall * auct = ah->GetStall(Stall_id);
if(auct == 0 || !auct->Owner || !_player || auct->Owner == _player->GetGUID())
return;
if(auct->HighestBid > price && price != auct->BuyoutPrice)
return;
if(_player->GetUInt32Value(PLAYER_FIELD_COINAGE) < price)
return;
_player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -((int32)price));
if(auct->HighestBidder != 0)
{
// Return the money to the last highest bidder.
char subject[100];
snprintf(subject, 100, "%u:0:0", (int)auct->pItem->GetEntry());
sMailSystem.SendAutomatedMessage(Stall, ah->GetID(), auct->HighestBidder, subject, "", auct->HighestBid,
0, 0, 62);
}
if(auct->BuyoutPrice == price)
{
auct->HighestBidder = _player->GetLowGUID();
auct->HighestBid = price;
// we used buyout on the item.
ah->QueueDeletion(auct, Stall_REMOVE_WON);
// send response packet
WorldPacket data(SMSG_Stall_COMMAND_RESULT, 12);
data << auct->Id << uint32(Stall_CANCEL) << uint32(0) << uint32(0);
SendPacket(&data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -