2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
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"
29 //pls DO NOT use iterator++, because it is slowlier than ++iterator!!!
30 //post-incrementation is always slowlier than pre-incrementation !
32 //void called when player click on auctionhouse npc
33 void WorldSession::HandleAuctionHelloOpcode( WorldPacket
& recv_data
)
35 CHECK_PACKET_SIZE(recv_data
,8);
37 uint64 guid
; //NPC guid
41 return; //check for cheaters
43 Creature
*unit
= ObjectAccessor::Instance().GetCreature(*_player
, guid
);
46 sLog
.outDebug( "WORLD: HandleAuctionHelloOpcode - NO SUCH UNIT! (GUID: %u)", uint32(GUID_LOPART(guid
)) );
49 if( unit
->IsHostileTo(_player
)) // do not talk with enemies
51 if( !unit
->isAuctioner()) // it's not auctioner
54 SendAuctionHello(guid
, unit
);
57 static uint8
AuctioneerFactionToLocation(uint32 faction
)
59 if(sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_TRADE
))
74 default: // 85 and so on ... neutral
79 //this void causes that auction window is opened
80 void WorldSession::SendAuctionHello( uint64 guid
, Creature
* unit
)
82 WorldPacket
data( MSG_AUCTION_HELLO
, 12 );
83 data
<< (uint64
) guid
;
84 data
<< (uint32
) AuctioneerFactionToLocation(unit
->getFaction());
88 //this function inserts to WorldPacket auction's data
89 bool WorldSession::SendAuctionInfo(WorldPacket
& data
, AuctionEntry
* auction
)
91 Item
*pItem
= objmgr
.GetAItem(auction
->item_guid
);
94 sLog
.outError("auction to item, that doesn't exist !!!!");
98 data
<< pItem
->GetUInt32Value(OBJECT_FIELD_ENTRY
);
99 data
<< (uint32
) pItem
->GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+0*3+0);
100 // Permanent enchantment id
101 data
<< (uint32
) pItem
->GetItemRandomPropertyId(); //random item properity id
102 data
<< (uint32
) 0; //not pItem->GetCreator();// 4a d0 64 02, 0, unknown, maybe enchating
103 data
<< (uint32
) pItem
->GetCount(); //item->count
104 //item->charge FFFFFFF
105 data
<< (uint32
) pItem
->GetUInt32Value(ITEM_FIELD_SPELL_CHARGES
);
106 data
<< (uint32
) auction
->owner
; //Auction->owner
107 data
<< (uint32
) 0; //player_high_guid
108 data
<< (uint32
) auction
->startbid
; //Auction->startbid
109 data
<< (uint32
) auction
->outBid
; //minimal outbid...
110 data
<< (uint32
) auction
->buyout
; //auction->buyout
111 data
<< (uint32
) (auction
->time
- time(NULL
)) * 1000; //time
112 data
<< (uint32
) auction
->bidder
; //auction->bidder current
113 data
<< (uint32
) 0; //player highguid
114 data
<< (uint32
) auction
->bid
; //current bid
118 //call this method when player bids, creates, or deletes auction
119 void WorldSession::SendAuctionCommandResult(uint32 auctionId
, uint32 Action
, uint32 ErrorCode
, uint32 bidError
)
121 WorldPacket
data( SMSG_AUCTION_COMMAND_RESULT
, 16 );
125 if ( !ErrorCode
&& Action
)
126 data
<< bidError
; //when bid, then send 0, once...
130 //this function sends notification, if bidder is online
131 void WorldSession::SendAuctionBidderNotification( uint32 location
, uint32 auctionId
, uint64 bidder
, uint32 bidSum
, uint32 diff
, uint32 item_template
)
133 WorldPacket
data(SMSG_AUCTION_BIDDER_NOTIFICATION
, (8*4));
136 data
<< (uint64
) bidder
;
138 data
<< (uint32
) diff
;
139 data
<< item_template
;
144 //this void causes on client to display: "Your auction sold"
145 void WorldSession::SendAuctionOwnerNotification( AuctionEntry
* auction
)
147 WorldPacket
data(SMSG_AUCTION_OWNER_NOTIFICATION
, (7*4));
149 data
<< auction
->bid
;
150 data
<< (uint32
) 0; //unk
151 data
<< (uint32
) 0; //unk
152 data
<< (uint32
) 0; //unk
153 data
<< auction
->item_template
;
154 data
<< (uint32
) 0; //unk
158 //this function sends mail to old bidder
159 void WorldSession::SendAuctionOutbiddedMail(AuctionEntry
*auction
, uint32 newPrice
)
161 uint32 mailId
= objmgr
.GenerateMailID();
162 time_t etime
= time(NULL
) + (30 * DAY
);
164 std::ostringstream msgAuctionOutbiddedSubject
;
165 msgAuctionOutbiddedSubject
<< auction
->item_template
<< ":0:" << AUCTION_OUTBIDDED
;
167 Player
*oldBidder
= objmgr
.GetPlayer((uint64
) auction
->bidder
);
170 oldBidder
->GetSession()->SendAuctionBidderNotification( auction
->location
, auction
->Id
, _player
->GetGUID(), newPrice
, auction
->outBid
, auction
->item_template
);
171 oldBidder
->CreateMail(mailId
, AUCTIONHOUSE_MAIL
, auction
->location
, msgAuctionOutbiddedSubject
.str(), 0, 0, 0, etime
, auction
->bid
, 0, NOT_READ
, NULL
);
174 sDatabase
.PExecute("INSERT INTO `mail` (`id`,`messageType`,`sender`,`receiver`,`subject`,`itemTextId`,`item_guid`,`item_template`,`time`,`money`,`cod`,`checked`) "
175 "VALUES ('%u', '%d', '%u', '%u', '%s', '0', '0', '0', '" I64FMTD
"', '%u', '0', '%d')",
176 mailId
, AUCTIONHOUSE_MAIL
, auction
->location
, auction
->bidder
, msgAuctionOutbiddedSubject
.str().c_str(), (uint64
)etime
, auction
->bid
, NOT_READ
);
179 //this function sends mail, when auction is cancelled to old bidder
180 void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry
* auction
)
182 uint32 mailId
= objmgr
.GenerateMailID();
183 time_t etime
= time(NULL
) + (30 * DAY
);
185 std::ostringstream msgAuctionCancelledSubject
;
186 msgAuctionCancelledSubject
<< auction
->item_template
<< ":0:" << AUCTION_CANCELLED_TO_BIDDER
;
188 Player
*bidder
= objmgr
.GetPlayer((uint64
) auction
->bidder
);
191 // unknown : bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, newPrice - auction->bid, auction->item_template);
192 bidder
->CreateMail(mailId
, AUCTIONHOUSE_MAIL
, auction
->location
, msgAuctionCancelledSubject
.str(), 0, 0, 0, etime
, auction
->bid
, 0, NOT_READ
, NULL
);
195 sDatabase
.PExecute("INSERT INTO `mail` (`id`,`messageType`,`sender`,`receiver`,`subject`,`itemTextId`,`item_guid`,`item_template`,`time`,`money`,`cod`,`checked`) "
196 "VALUES ('%u', '%d', '%u', '%u', '%s', '0', '0', '0', '" I64FMTD
"', '%u', '0', '%d')",
197 mailId
, AUCTIONHOUSE_MAIL
, auction
->location
, auction
->bidder
, msgAuctionCancelledSubject
.str().c_str(), (uint64
)etime
, auction
->bid
, NOT_READ
);
200 //this void creates new auction and adds auction to some auctionhouse
201 void WorldSession::HandleAuctionSellItem( WorldPacket
& recv_data
)
203 CHECK_PACKET_SIZE(recv_data
,8+8+4+4+4);
205 uint64 auctioneer
, item
;
206 uint32 etime
, bid
, buyout
;
207 recv_data
>> auctioneer
>> item
;
208 recv_data
>> bid
>> buyout
>> etime
;
209 Player
*pl
= GetPlayer();
211 if (!auctioneer
|| !item
|| !bid
|| !etime
)
212 return; //check for cheaters
214 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, auctioneer
);
215 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
218 uint16 pos
= pl
->GetPosByGuid(item
);
219 Item
*it
= pl
->GetItemByPos( pos
);
220 //do not allow to sell already auctioned items
221 if(objmgr
.GetAItem(GUID_LOPART(item
)))
223 sLog
.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl
->GetName(), GUID_LOPART(item
));
224 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_INTERNAL_ERROR
);
227 // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
228 if(!it
|| !it
->CanBeTraded())
230 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_INTERNAL_ERROR
);
234 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
235 AuctionHouseObject
* mAuctions
;
236 mAuctions
= objmgr
.GetAuctionsMap( location
);
238 //we have to take deposit :
239 uint32 deposit
= objmgr
.GetAuctionDeposit( location
, etime
, it
);
240 if ( pl
->GetMoney() < deposit
)
242 SendAuctionCommandResult(0, AUCTION_SELL_ITEM
, AUCTION_NOT_ENOUGHT_MONEY
);
245 pl
->ModifyMoney( ((int32
) deposit
) * -1 );
247 AuctionEntry
*AH
= new AuctionEntry
;
248 AH
->Id
= objmgr
.GenerateAuctionID();
249 AH
->auctioneer
= GUID_LOPART(auctioneer
);
250 AH
->item_guid
= GUID_LOPART(item
);
251 AH
->item_template
= it
->GetEntry();
252 AH
->owner
= pl
->GetGUIDLow();
258 time_t base
= time(NULL
);
259 AH
->time
= ((time_t)(etime
* 60)) + base
;
260 AH
->deposit
= deposit
;
261 AH
->location
= location
;
263 sLog
.outDetail("selling item %u to auctioneer %u with inital bid %u with buyout %u and with time %u (in minutes) in location: %u", GUID_LOPART(item
), GUID_LOPART(auctioneer
), bid
, buyout
, GUID_LOPART(time
), location
);
264 mAuctions
->AddAuction(AH
);
267 pl
->RemoveItem( (pos
>> 8),(pos
& 255), true);
268 it
->RemoveFromUpdateQueueOf(pl
);
270 sDatabase
.BeginTransaction();
271 it
->DeleteFromInventoryDB();
272 it
->SaveToDB(); // recursive and not have transaction guard into self
273 sDatabase
.PExecute("INSERT INTO `auctionhouse` (`id`,`auctioneerguid`,`itemguid`,`item_template`,`itemowner`,`buyoutprice`,`time`,`buyguid`,`lastbid`,`startbid`,`deposit`,`location`) "
274 "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD
"', '%u', '%u', '%u', '%u', '%u')",
275 AH
->Id
, AH
->auctioneer
, AH
->item_guid
, AH
->item_template
, AH
->owner
, AH
->buyout
, (uint64
)AH
->time
, AH
->bidder
, AH
->bid
, AH
->startbid
, AH
->deposit
, AH
->location
);
276 pl
->SaveInventoryAndGoldToDB();
277 sDatabase
.CommitTransaction();
279 SendAuctionCommandResult(AH
->Id
, AUCTION_SELL_ITEM
, AUCTION_OK
);
282 //this function is called when client bids or buys out auction
283 void WorldSession::HandleAuctionPlaceBid( WorldPacket
& recv_data
)
285 CHECK_PACKET_SIZE(recv_data
,8+4+4);
290 recv_data
>> auctioneer
;
291 recv_data
>> auctionId
>> price
;
293 if (!auctioneer
|| !auctionId
|| !price
)
294 return; //check for cheaters
296 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, auctioneer
);
297 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
300 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
302 AuctionHouseObject
* mAuctions
;
303 mAuctions
= objmgr
.GetAuctionsMap( location
);
305 AuctionEntry
*auction
= mAuctions
->GetAuction(auctionId
);
306 Player
*pl
= GetPlayer();
307 if ((auction
) && (auction
->owner
!= pl
->GetGUIDLow()))
309 if (price
< (auction
->bid
+ auction
->outBid
))
311 //auction has already higher bid, client tests it!
312 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
315 if (price
> pl
->GetMoney())
317 //you don't have enought money!, client tests!
318 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
321 if ((price
< auction
->buyout
) || (auction
->buyout
== 0))
323 auction
->outBid
+= 5; //this line must be here
325 if (auction
->bidder
> 0)
327 if ( auction
->bidder
== pl
->GetGUIDLow() )
329 pl
->ModifyMoney(((uint32
)(price
- auction
->bid
)) * -1);
333 // mail to last bidder and return money
334 SendAuctionOutbiddedMail( auction
, price
);
335 pl
->ModifyMoney(((int32
) price
) * -1);
340 pl
->ModifyMoney(((int32
) price
) * -1);
342 auction
->bidder
= pl
->GetGUIDLow();
343 auction
->bid
= price
;
344 if ( auction
->outBid
> 10000 ) //one gold
347 // after this update we should save player's money ...
348 sDatabase
.PExecute("UPDATE `auctionhouse` SET `buyguid` = '%u',`lastbid` = '%u' WHERE `id` = '%u';", auction
->bidder
, auction
->bid
, auction
->Id
);
350 SendAuctionCommandResult(auction
->Id
, AUCTION_PLACE_BID
, AUCTION_OK
, 0 );
355 if (pl
->GetGUIDLow() == auction
->bidder
)
357 pl
->ModifyMoney(-int32(auction
->buyout
- auction
->bid
));
361 pl
->ModifyMoney(-int32(auction
->buyout
));
362 if ( auction
->bidder
) //buyout for bidded auction ..
364 SendAuctionOutbiddedMail( auction
, auction
->buyout
);
367 auction
->bidder
= pl
->GetGUIDLow();
368 auction
->bid
= auction
->buyout
;
370 objmgr
.SendAuctionSuccessfulMail( auction
);
371 objmgr
.SendAuctionWonMail( auction
);
373 SendAuctionCommandResult(auction
->Id
, AUCTION_PLACE_BID
, AUCTION_OK
);
375 objmgr
.RemoveAItem(auction
->item_guid
);
376 mAuctions
->RemoveAuction(auction
->Id
);
377 sDatabase
.PExecute("DELETE FROM `auctionhouse` WHERE `id` = '%u'",auction
->Id
);
381 sDatabase
.BeginTransaction();
382 pl
->SaveInventoryAndGoldToDB();
383 sDatabase
.CommitTransaction();
387 //you cannot bid your own auction:
388 SendAuctionCommandResult( 0, AUCTION_PLACE_BID
, CANNOT_BID_YOUR_AUCTION_ERROR
);
392 //this void is called when auction_owner cancels his auction
393 void WorldSession::HandleAuctionRemoveItem( WorldPacket
& recv_data
)
395 CHECK_PACKET_SIZE(recv_data
,8+4);
399 recv_data
>> auctioneer
;
400 recv_data
>> auctionId
;
401 //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId);
403 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, auctioneer
);
404 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
407 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
409 AuctionHouseObject
* mAuctions
;
410 mAuctions
= objmgr
.GetAuctionsMap( location
);
412 AuctionEntry
*auction
= mAuctions
->GetAuction(auctionId
);
413 Player
*pl
= GetPlayer();
415 if (auction
&& auction
->owner
== pl
->GetGUIDLow())
417 Item
*pItem
= objmgr
.GetAItem(auction
->item_guid
);
420 if (auction
->bidder
> 0) // If we have a bidder, we have to send him the money he paid
422 uint32 auctionCut
= objmgr
.GetAuctionCut( auction
->location
, auction
->bid
);
423 if ( pl
->GetMoney() < auctionCut
) //player doesn't have enought money, maybe message needed
425 //some auctionBidderNotification would be needed, but don't know that parts..
426 SendAuctionCancelledToBidderMail( auction
);
427 pl
->ModifyMoney( ((int32
) auctionCut
) * -1 );
429 // Return the item by mail
430 std::ostringstream msgAuctionCanceledOwner
;
431 msgAuctionCanceledOwner
<< auction
->item_template
<< ":0:" << AUCTION_CANCELED
;
433 uint32 messageID
= objmgr
.GenerateMailID();
434 time_t etime
= time(NULL
) + (30 * DAY
);
436 pl
->CreateMail( messageID
, AUCTIONHOUSE_MAIL
, auction
->location
, msgAuctionCanceledOwner
.str(), 0, auction
->item_guid
, auction
->item_template
, etime
, 0, 0, 0, pItem
);
437 sDatabase
.PExecute("INSERT INTO `mail` (`id`,`messageType`,`sender`,`receiver`,`subject`,`itemTextId`,`item_guid`,`item_template`,`time`,`money`,`cod`,`checked`) "
438 "VALUES ('%u', '%d', '%u', '%u', '%s', '0', '%u', '%u', '" I64FMTD
"', '0', '0', '0')",
439 messageID
, AUCTIONHOUSE_MAIL
, auction
->location
, pl
->GetGUIDLow() , msgAuctionCanceledOwner
.str().c_str(), auction
->item_guid
, auction
->item_template
, (uint64
)etime
);
444 sLog
.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction
->Id
, auction
->item_guid
);
445 SendAuctionCommandResult( 0, AUCTION_CANCEL
, AUCTION_INTERNAL_ERROR
);
451 SendAuctionCommandResult( 0, AUCTION_CANCEL
, AUCTION_INTERNAL_ERROR
);
452 //this code isn't possible ... maybe there should be assert
453 sLog
.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl
->GetGUIDLow(), auctionId
);
457 //inform player, that auction is removed
458 SendAuctionCommandResult( auction
->Id
, AUCTION_CANCEL
, AUCTION_OK
);
459 // Now remove the auction
460 sDatabase
.BeginTransaction();
461 sDatabase
.PExecute("DELETE FROM `auctionhouse` WHERE `id` = '%u'",auction
->Id
);
462 pl
->SaveInventoryAndGoldToDB();
463 sDatabase
.CommitTransaction();
464 objmgr
.RemoveAItem( auction
->item_guid
);
465 mAuctions
->RemoveAuction( auction
->Id
);
469 //called when player lists his bids
470 void WorldSession::HandleAuctionListBidderItems( WorldPacket
& recv_data
)
472 CHECK_PACKET_SIZE(recv_data
,8+4+4);
474 uint64 guid
; //NPC guid
475 uint32 listfrom
; //page of auctions
476 uint32 outbiddedCount
; //count of outbidded auctions
479 recv_data
>> listfrom
;
480 recv_data
>> outbiddedCount
;
481 if (recv_data
.size() != (16 + outbiddedCount
* 4 ))
483 sLog
.outError("Client sent bad opcode!!! with count: %u and size : %d (mustbe: %d", outbiddedCount
, recv_data
.size(),(16 + outbiddedCount
* 4 ));
487 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, guid
);
488 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
491 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
493 AuctionHouseObject
* mAuctions
;
494 mAuctions
= objmgr
.GetAuctionsMap( location
);
496 WorldPacket
data( SMSG_AUCTION_BIDDER_LIST_RESULT
, (4+4+4) );
497 Player
*pl
= GetPlayer();
498 data
<< (uint32
) 0; //add 0 as count
500 uint32 totalcount
= 0;
501 while ( outbiddedCount
> 0) //add all data, which client requires
504 uint32 outbiddedAuctionId
;
505 recv_data
>> outbiddedAuctionId
;
506 AuctionEntry
* auction
= mAuctions
->GetAuction( outbiddedAuctionId
);
507 if ( auction
&& SendAuctionInfo(data
, auction
))
513 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
515 AuctionEntry
*Aentry
= itr
->second
;
516 if( Aentry
&& Aentry
->bidder
== pl
->GetGUIDLow() )
518 if ((count
< 50) && (totalcount
>= listfrom
) && SendAuctionInfo(data
, itr
->second
))
523 data
.put( 0, count
); // add count to placeholder
528 //this void sends player info about his auctions
529 void WorldSession::HandleAuctionListOwnerItems( WorldPacket
& recv_data
)
531 CHECK_PACKET_SIZE(recv_data
,8+4);
537 recv_data
>> listfrom
; // page of auctions
539 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, guid
);
540 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
543 uint32 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
545 AuctionHouseObject
* mAuctions
;
546 mAuctions
= objmgr
.GetAuctionsMap( location
);
548 WorldPacket
data( SMSG_AUCTION_OWNER_LIST_RESULT
, (4+4+4) );
551 uint32 totalcount
= 0;
552 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
554 AuctionEntry
*Aentry
= itr
->second
;
555 if( Aentry
&& Aentry
->owner
== _player
->GetGUIDLow() )
557 if ((count
< 50) && (totalcount
>= listfrom
) && SendAuctionInfo(data
, itr
->second
))
562 data
.put
<uint32
>(0, count
);
563 data
<< (uint32
) totalcount
;
567 //this void is called when player clicks on search button
568 void WorldSession::HandleAuctionListItems( WorldPacket
& recv_data
)
570 CHECK_PACKET_SIZE(recv_data
,8+4+1+1+1+4+4+4+4+1);
572 std::string searchedname
, name
;
573 uint8 levelmin
, levelmax
, usable
, location
;
574 uint32 count
, totalcount
, listfrom
, auctionSlotID
, auctionMainCategory
, auctionSubCategory
, quality
;
578 recv_data
>> listfrom
;
579 recv_data
>> searchedname
;
581 // recheck with known string size
582 CHECK_PACKET_SIZE(recv_data
,8+4+(searchedname
.size()+1)+1+1+4+4+4+4+1);
584 recv_data
>> levelmin
>> levelmax
;
585 recv_data
>> auctionSlotID
>> auctionMainCategory
>> auctionSubCategory
;
586 recv_data
>> quality
>> usable
;
588 Creature
*pCreature
= ObjectAccessor::Instance().GetCreature(*_player
, guid
);
589 if( !pCreature
|| !pCreature
->isAuctioner() || pCreature
->IsHostileTo(GetPlayer()) || !pCreature
->IsWithinDistInMap(GetPlayer(),OBJECT_ITERACTION_DISTANCE
))
592 location
= AuctioneerFactionToLocation(pCreature
->getFaction());
593 AuctionHouseObject
* mAuctions
;
594 mAuctions
= objmgr
.GetAuctionsMap( location
);
596 //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);
598 WorldPacket
data( SMSG_AUCTION_LIST_RESULT
, (4+4+4) );
602 for (AuctionHouseObject::AuctionEntryMap::iterator itr
= mAuctions
->GetAuctionsBegin();itr
!= mAuctions
->GetAuctionsEnd();++itr
)
604 AuctionEntry
*Aentry
= itr
->second
;
605 Item
*item
= objmgr
.GetAItem(Aentry
->item_guid
);
608 ItemPrototype
const *proto
= item
->GetProto();
611 if( auctionMainCategory
== (0xffffffff) || proto
->Class
== auctionMainCategory
)
613 if( auctionSubCategory
== (0xffffffff) || proto
->SubClass
== auctionSubCategory
)
615 if( auctionSlotID
== (0xffffffff) || proto
->InventoryType
== auctionSlotID
)
617 if( quality
== (0xffffffff) || proto
->Quality
== quality
)
619 if( usable
== (0x00) || _player
->CanUseItem( item
) == EQUIP_ERR_OK
)
621 if( ( levelmin
== (0x00) || proto
->RequiredLevel
>= levelmin
) && ( levelmax
== (0x00) || proto
->RequiredLevel
<= levelmax
) )
624 std::transform( name
.begin(), name
.end(), name
.begin(), ::tolower
);
625 std::transform( searchedname
.begin(), searchedname
.end(), searchedname
.begin(), ::tolower
);
626 if( searchedname
.empty() || name
.find( searchedname
) != std::string::npos
)
628 if ((count
< 50) && (totalcount
>= listfrom
))
631 SendAuctionInfo( data
, Aentry
);
644 data
.put
<uint32
>(0, count
);
645 data
<< (uint32
) totalcount
;