2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "WorldPacket.h"
20 #include "WorldSession.h"
24 #include "ObjectMgr.h"
26 #include "UpdateMask.h"
27 #include "AuctionHouseObject.h"
30 //please DO NOT use iterator++, because it is slower than ++iterator!!!
31 //post-incrementation is always slower than pre-incrementation !
33 //void called when player click on auctioneer npc
34 void WorldSession::HandleAuctionHelloOpcode( WorldPacket
& recv_data
)
36 CHECK_PACKET_SIZE(recv_data
,8);
38 uint64 guid
; //NPC guid
41 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_AUCTIONEER
);
44 sLog
.outDebug( "WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
49 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
50 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
52 SendAuctionHello(guid
, unit
);
55 static uint8
AuctioneerFactionToLocation(uint32 faction
)
57 if(sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
60 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(faction
);
64 if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
66 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
72 //this void causes that auction window is opened
73 void WorldSession::SendAuctionHello( uint64 guid
, Creature
* unit
)
75 WorldPacket
data( MSG_AUCTION_HELLO
, 12 );
76 data
<< (uint64
) guid
;
77 data
<< (uint32
) AuctioneerFactionToLocation(unit
->getFaction());
81 //this function inserts to WorldPacket auction's data
82 bool WorldSession::SendAuctionInfo(WorldPacket
& data
, AuctionEntry
* auction
)
84 Item
*pItem
= objmgr
.GetAItem(auction
->item_guidlow
);
87 sLog
.outError("auction to item, that doesn't exist !!!!");
90 data
<< (uint32
) auction
->Id
;
91 data
<< (uint32
) pItem
->GetEntry();
93 for (uint8 i
= 0; i
< MAX_INSPECTED_ENCHANTMENT_SLOT
; i
++)
95 data
<< (uint32
) pItem
->GetEnchantmentId(EnchantmentSlot(i
));
96 data
<< (uint32
) pItem
->GetEnchantmentDuration(EnchantmentSlot(i
));
97 data
<< (uint32
) pItem
->GetEnchantmentCharges(EnchantmentSlot(i
));
100 data
<< (uint32
) pItem
->GetItemRandomPropertyId(); //random item property id
101 data
<< (uint32
) pItem
->GetItemSuffixFactor(); //SuffixFactor
102 data
<< (uint32
) pItem
->GetCount(); //item->count
103 data
<< (uint32
) pItem
->GetSpellCharges(); //item->charge FFFFFFF
104 data
<< (uint32
) 0; //Unknown
105 data
<< (uint64
) auction
->owner
; //Auction->owner
106 data
<< (uint32
) auction
->startbid
; //Auction->startbid (not sure if useful)
107 data
<< (uint32
) ((auction
->bid
)? objmgr
.GetAuctionOutBid(auction
->bid
) : 0);
109 data
<< (uint32
) auction
->buyout
; //auction->buyout
110 data
<< (uint32
) (auction
->time
- time(NULL
)) * 1000; //time left
111 data
<< (uint64
) auction
->bidder
; //auction->bidder current
112 data
<< (uint32
) auction
->bid
; //current bid
116 //call this method when player bids, creates, or deletes auction
117 void WorldSession::SendAuctionCommandResult(uint32 auctionId
, uint32 Action
, uint32 ErrorCode
, uint32 bidError
)
119 WorldPacket
data( SMSG_AUCTION_COMMAND_RESULT
, 16 );
123 if ( !ErrorCode
&& Action
)
124 data
<< bidError
; //when bid, then send 0, once...
128 //this function sends notification, if bidder is online
129 void WorldSession::SendAuctionBidderNotification( uint32 location
, uint32 auctionId
, uint64 bidder
, uint32 bidSum
, uint32 diff
, uint32 item_template
)
131 WorldPacket
data(SMSG_AUCTION_BIDDER_NOTIFICATION
, (8*4));
134 data
<< (uint64
) bidder
;
136 data
<< (uint32
) diff
;
137 data
<< item_template
;
142 //this void causes on client to display: "Your auction sold"
143 void WorldSession::SendAuctionOwnerNotification( AuctionEntry
* auction
)
145 WorldPacket
data(SMSG_AUCTION_OWNER_NOTIFICATION
, (7*4));
147 data
<< auction
->bid
;
148 data
<< (uint32
) 0; //unk
149 data
<< (uint32
) 0; //unk
150 data
<< (uint32
) 0; //unk
151 data
<< auction
->item_template
;
152 data
<< (uint32
) 0; //unk
156 //this function sends mail to old bidder
157 void WorldSession::SendAuctionOutbiddedMail(AuctionEntry
*auction
, uint32 newPrice
)
159 uint64 oldBidder_guid
= MAKE_NEW_GUID(auction
->bidder
,0, HIGHGUID_PLAYER
);
160 Player
*oldBidder
= objmgr
.GetPlayer(oldBidder_guid
);
162 uint32 oldBidder_accId
= 0;
164 oldBidder_accId
= objmgr
.GetPlayerAccountIdByGUID(oldBidder_guid
);
167 if(oldBidder
|| oldBidder_accId
)
169 std::ostringstream msgAuctionOutbiddedSubject
;
170 msgAuctionOutbiddedSubject
<< auction
->item_template
<< ":0:" << AUCTION_OUTBIDDED
;
173 oldBidder
->GetSession()->SendAuctionBidderNotification( auction
->location
, auction
->Id
, _player
->GetGUID(), newPrice
, objmgr
.GetAuctionOutBid(auction
->bid
), auction
->item_template
);
175 WorldSession::SendMailTo(oldBidder
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->location
, auction
->bidder
, msgAuctionOutbiddedSubject
.str(), 0, NULL
, auction
->bid
, 0, MAIL_CHECK_MASK_NONE
);
179 //this function sends mail, when auction is cancelled to old bidder
180 void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry
* auction
)
182 uint64 bidder_guid
= MAKE_NEW_GUID(auction
->bidder
, 0, HIGHGUID_PLAYER
);
183 Player
*bidder
= objmgr
.GetPlayer(bidder_guid
);
185 uint32 bidder_accId
= 0;
187 bidder_accId
= objmgr
.GetPlayerAccountIdByGUID(bidder_guid
);
190 if(bidder
|| bidder_accId
)
192 std::ostringstream msgAuctionCancelledSubject
;
193 msgAuctionCancelledSubject
<< auction
->item_template
<< ":0:" << AUCTION_CANCELLED_TO_BIDDER
;
195 WorldSession::SendMailTo(bidder
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->location
, auction
->bidder
, msgAuctionCancelledSubject
.str(), 0, NULL
, auction
->bid
, 0, MAIL_CHECK_MASK_NONE
);
199 //this void creates new auction and adds auction to some auctionhouse
200 void WorldSession::HandleAuctionSellItem( WorldPacket
& recv_data
)
202 CHECK_PACKET_SIZE(recv_data
,8+8+4+4+4);
204 uint64 auctioneer
, item
;
205 uint32 etime
, bid
, buyout
;
206 recv_data
>> auctioneer
>> item
;
207 recv_data
>> bid
>> buyout
>> etime
;
208 Player
*pl
= GetPlayer();
210 if (!item
|| !bid
|| !etime
)
211 return; //check for cheaters
213 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, auctioneer
,UNIT_NPC_FLAG_AUCTIONEER
);
216 sLog
.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer
)) );
220 // client send time in minutes, convert to common used sec time
223 // client understand only 3 auction time
226 case 1*MIN_AUCTION_TIME
:
227 case 2*MIN_AUCTION_TIME
:
228 case 4*MIN_AUCTION_TIME
:
235 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
236 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
238 Item
*it
= pl
->GetItemByGuid( item
);
239 //do not allow to sell already auctioned items
240 if(objmgr
.GetAItem(GUID_LOPART(item
)))
242 sLog
.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl
->GetName(), GUID_LOPART(item
));
243 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_INTERNAL_ERROR
);
246 // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
249 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_ITEM_NOT_FOUND
);
253 if(!it
->CanBeTraded())
255 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_INTERNAL_ERROR
);
259 if (it
->HasFlag(ITEM_FIELD_FLAGS
, ITEM_FLAGS_CONJURED
) || it
->GetUInt32Value(ITEM_FIELD_DURATION
))
261 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_INTERNAL_ERROR
);
265 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
266 AuctionHouseObject
* mAuctions
;
267 mAuctions
= objmgr
.GetAuctionsMap( location
);
269 //we have to take deposit :
270 uint32 deposit
= objmgr
.GetAuctionDeposit( location
, etime
, it
);
271 if ( pl
->GetMoney() < deposit
)
273 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_NOT_ENOUGHT_MONEY
);
277 if( GetSecurity() > SEC_PLAYER
&& sWorld
.getConfig(CONFIG_GM_LOG_TRADE
) )
279 sLog
.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
280 GetPlayerName(),GetAccountId(),it
->GetProto()->Name1
,it
->GetEntry(),it
->GetCount());
283 pl
->ModifyMoney( -int32(deposit
) );
285 uint32 auction_time
= uint32(etime
* sWorld
.getRate(RATE_AUCTION_TIME
));
287 AuctionEntry
*AH
= new AuctionEntry
;
288 AH
->Id
= objmgr
.GenerateAuctionID();
289 AH
->auctioneer
= GUID_LOPART(auctioneer
);
290 AH
->item_guidlow
= GUID_LOPART(item
);
291 AH
->item_template
= it
->GetEntry();
292 AH
->owner
= pl
->GetGUIDLow();
297 AH
->time
= time(NULL
) + auction_time
;
298 AH
->deposit
= deposit
;
299 AH
->location
= location
;
301 sLog
.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in location: %u", GUID_LOPART(item
), GUID_LOPART(auctioneer
), bid
, buyout
, auction_time
, location
);
302 mAuctions
->AddAuction(AH
);
305 pl
->MoveItemFromInventory( it
->GetBagSlot(), it
->GetSlot(), true);
307 CharacterDatabase
.BeginTransaction();
308 it
->DeleteFromInventoryDB();
309 it
->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
310 CharacterDatabase
.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location) "
311 "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD
"', '%u', '%u', '%u', '%u', '%u')",
312 AH
->Id
, AH
->auctioneer
, AH
->item_guidlow
, AH
->item_template
, AH
->owner
, AH
->buyout
, (uint64
)AH
->time
, AH
->bidder
, AH
->bid
, AH
->startbid
, AH
->deposit
, AH
->location
);
313 pl
->SaveInventoryAndGoldToDB();
314 CharacterDatabase
.CommitTransaction();
316 SendAuctionCommandResult(AH
->Id
, AUCTION_SELL_ITEM
, AUCTION_OK
);
319 //this function is called when client bids or buys out auction
320 void WorldSession::HandleAuctionPlaceBid( WorldPacket
& recv_data
)
322 CHECK_PACKET_SIZE(recv_data
,8+4+4);
327 recv_data
>> auctioneer
;
328 recv_data
>> auctionId
>> price
;
330 if (!auctionId
|| !price
)
331 return; //check for cheaters
333 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, auctioneer
,UNIT_NPC_FLAG_AUCTIONEER
);
336 sLog
.outDebug( "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer
)) );
341 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
342 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
344 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
346 AuctionHouseObject
* mAuctions
;
347 mAuctions
= objmgr
.GetAuctionsMap( location
);
349 AuctionEntry
*auction
= mAuctions
->GetAuction(auctionId
);
350 Player
*pl
= GetPlayer();
352 if( !auction
|| auction
->owner
== pl
->GetGUIDLow() )
354 //you cannot bid your own auction:
355 SendAuctionCommandResult( 0, AUCTION_PLACE_BID
, CANNOT_BID_YOUR_AUCTION_ERROR
);
359 // impossible have online own another character (use this for speedup check in case online owner)
360 Player
* auction_owner
= objmgr
.GetPlayer(MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
));
361 if( !auction_owner
&& objmgr
.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
)) == pl
->GetSession()->GetAccountId())
363 //you cannot bid your another character auction:
364 SendAuctionCommandResult( 0, AUCTION_PLACE_BID
, CANNOT_BID_YOUR_AUCTION_ERROR
);
369 if(price
<= auction
->bid
)
372 // price too low for next bid if not buyout
373 if ((price
< auction
->buyout
|| auction
->buyout
== 0) &&
374 price
< auction
->bid
+ objmgr
.GetAuctionOutBid(auction
->bid
))
376 //auction has already higher bid, client tests it!
380 if (price
> pl
->GetMoney())
382 //you don't have enought money!, client tests!
383 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
387 if ((price
< auction
->buyout
) || (auction
->buyout
== 0))
389 if (auction
->bidder
> 0)
391 if ( auction
->bidder
== pl
->GetGUIDLow() )
393 pl
->ModifyMoney( -int32(price
- auction
->bid
));
397 // mail to last bidder and return money
398 SendAuctionOutbiddedMail( auction
, price
);
399 pl
->ModifyMoney( -int32(price
) );
404 pl
->ModifyMoney( -int32(price
) );
406 auction
->bidder
= pl
->GetGUIDLow();
407 auction
->bid
= price
;
409 // after this update we should save player's money ...
410 CharacterDatabase
.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction
->bidder
, auction
->bid
, auction
->Id
);
412 SendAuctionCommandResult(auction
->Id
, AUCTION_PLACE_BID
, AUCTION_OK
, 0 );
417 if (pl
->GetGUIDLow() == auction
->bidder
)
419 pl
->ModifyMoney(-int32(auction
->buyout
- auction
->bid
));
423 pl
->ModifyMoney(-int32(auction
->buyout
));
424 if ( auction
->bidder
) //buyout for bidded auction ..
426 SendAuctionOutbiddedMail( auction
, auction
->buyout
);
429 auction
->bidder
= pl
->GetGUIDLow();
430 auction
->bid
= auction
->buyout
;
432 objmgr
.SendAuctionSalePendingMail( auction
);
433 objmgr
.SendAuctionSuccessfulMail( auction
);
434 objmgr
.SendAuctionWonMail( auction
);
436 SendAuctionCommandResult(auction
->Id
, AUCTION_PLACE_BID
, AUCTION_OK
);
438 objmgr
.RemoveAItem(auction
->item_guidlow
);
439 mAuctions
->RemoveAuction(auction
->Id
);
440 CharacterDatabase
.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction
->Id
);
444 CharacterDatabase
.BeginTransaction();
445 pl
->SaveInventoryAndGoldToDB();
446 CharacterDatabase
.CommitTransaction();
449 //this void is called when auction_owner cancels his auction
450 void WorldSession::HandleAuctionRemoveItem( WorldPacket
& recv_data
)
452 CHECK_PACKET_SIZE(recv_data
,8+4);
456 recv_data
>> auctioneer
;
457 recv_data
>> auctionId
;
458 //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId);
460 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, auctioneer
,UNIT_NPC_FLAG_AUCTIONEER
);
463 sLog
.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer
)) );
468 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
469 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
471 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
473 AuctionHouseObject
* mAuctions
;
474 mAuctions
= objmgr
.GetAuctionsMap( location
);
476 AuctionEntry
*auction
= mAuctions
->GetAuction(auctionId
);
477 Player
*pl
= GetPlayer();
479 if (auction
&& auction
->owner
== pl
->GetGUIDLow())
481 Item
*pItem
= objmgr
.GetAItem(auction
->item_guidlow
);
484 if (auction
->bidder
> 0) // If we have a bidder, we have to send him the money he paid
486 uint32 auctionCut
= objmgr
.GetAuctionCut( auction
->location
, auction
->bid
);
487 if ( pl
->GetMoney() < auctionCut
) //player doesn't have enough money, maybe message needed
489 //some auctionBidderNotification would be needed, but don't know that parts..
490 SendAuctionCancelledToBidderMail( auction
);
491 pl
->ModifyMoney( -int32(auctionCut
) );
493 // Return the item by mail
494 std::ostringstream msgAuctionCanceledOwner
;
495 msgAuctionCanceledOwner
<< auction
->item_template
<< ":0:" << AUCTION_CANCELED
;
498 mi
.AddItem(auction
->item_guidlow
, auction
->item_template
, pItem
);
500 // item will deleted or added to received mail list
501 WorldSession::SendMailTo(pl
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->location
, pl
->GetGUIDLow(), msgAuctionCanceledOwner
.str(), 0, &mi
, 0, 0, MAIL_CHECK_MASK_NONE
);
505 sLog
.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction
->Id
, auction
->item_guidlow
);
506 SendAuctionCommandResult( 0, AUCTION_CANCEL
, AUCTION_INTERNAL_ERROR
);
512 SendAuctionCommandResult( 0, AUCTION_CANCEL
, AUCTION_INTERNAL_ERROR
);
513 //this code isn't possible ... maybe there should be assert
514 sLog
.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl
->GetGUIDLow(), auctionId
);
518 //inform player, that auction is removed
519 SendAuctionCommandResult( auction
->Id
, AUCTION_CANCEL
, AUCTION_OK
);
520 // Now remove the auction
521 CharacterDatabase
.BeginTransaction();
522 CharacterDatabase
.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction
->Id
);
523 pl
->SaveInventoryAndGoldToDB();
524 CharacterDatabase
.CommitTransaction();
525 objmgr
.RemoveAItem( auction
->item_guidlow
);
526 mAuctions
->RemoveAuction( auction
->Id
);
530 //called when player lists his bids
531 void WorldSession::HandleAuctionListBidderItems( WorldPacket
& recv_data
)
533 CHECK_PACKET_SIZE(recv_data
,8+4+4);
535 uint64 guid
; //NPC guid
536 uint32 listfrom
; //page of auctions
537 uint32 outbiddedCount
; //count of outbidded auctions
540 recv_data
>> listfrom
; // not used in fact (this list not have page control in client)
541 recv_data
>> outbiddedCount
;
542 if (recv_data
.size() != (16 + outbiddedCount
* 4 ))
544 sLog
.outError("Client sent bad opcode!!! with count: %u and size : %d (mustbe: %d", outbiddedCount
, recv_data
.size(),(16 + outbiddedCount
* 4 ));
548 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_AUCTIONEER
);
551 sLog
.outDebug( "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
556 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
557 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
559 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
560 AuctionHouseObject
* mAuctions
= objmgr
.GetAuctionsMap( location
);
562 WorldPacket
data( SMSG_AUCTION_BIDDER_LIST_RESULT
, (4+4+4) );
563 Player
*pl
= GetPlayer();
564 data
<< (uint32
) 0; //add 0 as count
566 uint32 totalcount
= 0;
567 while ( outbiddedCount
> 0) //add all data, which client requires
570 uint32 outbiddedAuctionId
;
571 recv_data
>> outbiddedAuctionId
;
572 AuctionEntry
* auction
= mAuctions
->GetAuction( outbiddedAuctionId
);
573 if ( auction
&& SendAuctionInfo(data
, auction
))
579 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
581 AuctionEntry
*Aentry
= itr
->second
;
582 if( Aentry
&& Aentry
->bidder
== pl
->GetGUIDLow() )
584 if (SendAuctionInfo(data
, itr
->second
))
589 data
.put
<uint32
>( 0, count
); // add count to placeholder
591 data
<< (uint32
)300; //unk 2.3.0
595 //this void sends player info about his auctions
596 void WorldSession::HandleAuctionListOwnerItems( WorldPacket
& recv_data
)
598 CHECK_PACKET_SIZE(recv_data
,8+4);
604 recv_data
>> listfrom
; // not used in fact (this list not have page control in client)
606 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_AUCTIONEER
);
609 sLog
.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
614 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
615 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
617 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
619 AuctionHouseObject
* mAuctions
= objmgr
.GetAuctionsMap( location
);
621 WorldPacket
data( SMSG_AUCTION_OWNER_LIST_RESULT
, (4+4+4) );
622 data
<< (uint32
) 0; // amount place holder
625 uint32 totalcount
= 0;
626 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
628 AuctionEntry
*Aentry
= itr
->second
;
629 if( Aentry
&& Aentry
->owner
== _player
->GetGUIDLow() )
631 if(SendAuctionInfo(data
, itr
->second
))
636 data
.put
<uint32
>(0, count
);
637 data
<< (uint32
) totalcount
;
642 //this void is called when player clicks on search button
643 void WorldSession::HandleAuctionListItems( WorldPacket
& recv_data
)
645 CHECK_PACKET_SIZE(recv_data
,8+4+1+1+1+4+4+4+4+1);
647 std::string searchedname
, name
;
648 uint8 levelmin
, levelmax
, usable
, location
;
649 uint32 count
, totalcount
, listfrom
, auctionSlotID
, auctionMainCategory
, auctionSubCategory
, quality
;
653 recv_data
>> listfrom
; // start, used for page control listing by 50 elements
654 recv_data
>> searchedname
;
656 // recheck with known string size
657 CHECK_PACKET_SIZE(recv_data
,8+4+(searchedname
.size()+1)+1+1+4+4+4+4+1);
659 recv_data
>> levelmin
>> levelmax
;
660 recv_data
>> auctionSlotID
>> auctionMainCategory
>> auctionSubCategory
;
661 recv_data
>> quality
>> usable
;
663 Creature
*pCreature
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_AUCTIONEER
);
666 sLog
.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
671 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
672 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
674 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
675 AuctionHouseObject
* mAuctions
;
676 mAuctions
= objmgr
.GetAuctionsMap( location
);
678 //sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
680 WorldPacket
data( SMSG_AUCTION_LIST_RESULT
, (4+4+4) );
685 // converting string that we try to find to lower case
686 std::wstring wsearchedname
;
687 if(!Utf8toWStr(searchedname
,wsearchedname
))
690 wstrToLower(wsearchedname
);
692 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
694 AuctionEntry
*Aentry
= itr
->second
;
695 Item
*item
= objmgr
.GetAItem(Aentry
->item_guidlow
);
698 ItemPrototype
const *proto
= item
->GetProto();
701 if( auctionMainCategory
== (0xffffffff) || proto
->Class
== auctionMainCategory
)
703 if( auctionSubCategory
== (0xffffffff) || proto
->SubClass
== auctionSubCategory
)
705 if( auctionSlotID
== (0xffffffff) || proto
->InventoryType
== auctionSlotID
)
707 if( quality
== (0xffffffff) || proto
->Quality
== quality
)
709 if( usable
== (0x00) || _player
->CanUseItem( item
) == EQUIP_ERR_OK
)
711 if( ( levelmin
== (0x00) || proto
->RequiredLevel
>= levelmin
) && ( levelmax
== (0x00) || proto
->RequiredLevel
<= levelmax
) )
716 int loc_idx
= GetSessionDbLocaleIndex();
719 ItemLocale
const *il
= objmgr
.GetItemLocale(proto
->ItemId
);
722 if (il
->Name
.size() > size_t(loc_idx
) && !il
->Name
[loc_idx
].empty())
723 name
= il
->Name
[loc_idx
];
730 if( wsearchedname
.empty() || Utf8FitTo(name
, wsearchedname
) )
732 if ((count
< 50) && (totalcount
>= listfrom
))
735 SendAuctionInfo( data
, Aentry
);
748 data
.put
<uint32
>(0, count
);
749 data
<< (uint32
) totalcount
;
750 data
<< (uint32
) 300; // unk 2.3.0 const?
754 void WorldSession::HandleAuctionListPendingSales( WorldPacket
& recv_data
)
756 sLog
.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
761 WorldPacket
data(SMSG_AUCTION_LIST_PENDING_SALES
, 4);
762 data
<< uint32(count
); // count
763 /*for(uint32 i = 0; i < count; ++i)
765 data << ""; // string
766 data << ""; // string