AHBot for 3.1.x
[AHbot.git] / src / game / AuctionHouseHandler.cpp
blob0b5ff6a8f6e9e19786323a4c9bc4db946334b566
1 /*
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"
21 #include "Opcodes.h"
22 #include "Log.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "Player.h"
26 #include "UpdateMask.h"
27 #include "AuctionHouseMgr.h"
28 #include "Util.h"
29 #include "AuctionHouseBot.h"
31 //please DO NOT use iterator++, because it is slower than ++iterator!!!
32 //post-incrementation is always slower than pre-incrementation !
34 //void called when player click on auctioneer npc
35 void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data )
37 CHECK_PACKET_SIZE(recv_data,8);
39 uint64 guid; //NPC guid
40 recv_data >> guid;
42 Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
43 if (!unit)
45 sLog.outDebug( "WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
46 return;
49 // remove fake death
50 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
51 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
53 SendAuctionHello(guid, unit);
56 //this void causes that auction window is opened
57 void WorldSession::SendAuctionHello( uint64 guid, Creature* unit )
59 AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction());
60 if(!ahEntry)
61 return;
63 WorldPacket data( MSG_AUCTION_HELLO, 12 );
64 data << (uint64) guid;
65 data << (uint32) ahEntry->houseId;
66 SendPacket( &data );
69 //call this method when player bids, creates, or deletes auction
70 void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError )
72 WorldPacket data( SMSG_AUCTION_COMMAND_RESULT, 16 );
73 data << auctionId;
74 data << Action;
75 data << ErrorCode;
76 if ( !ErrorCode && Action )
77 data << bidError; //when bid, then send 0, once...
78 SendPacket(&data);
81 //this function sends notification, if bidder is online
82 void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template)
84 WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4));
85 data << uint32(location);
86 data << uint32(auctionId);
87 data << uint64(bidder);
88 data << uint32(bidSum);
89 data << uint32(diff);
90 data << uint32(item_template);
91 data << uint32(0);
92 SendPacket(&data);
95 //this void causes on client to display: "Your auction sold"
96 void WorldSession::SendAuctionOwnerNotification( AuctionEntry* auction)
98 WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4));
99 data << auction->Id;
100 data << auction->bid;
101 data << (uint32) 0; //unk
102 data << (uint32) 0; //unk
103 data << (uint32) 0; //unk
104 data << auction->item_template;
105 data << (uint32) 0; //unk
106 SendPacket(&data);
109 //this function sends mail to old bidder
110 void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice)
112 uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER);
113 Player *oldBidder = objmgr.GetPlayer(oldBidder_guid);
115 uint32 oldBidder_accId = 0;
116 if(!oldBidder)
117 oldBidder_accId = objmgr.GetPlayerAccountIdByGUID(oldBidder_guid);
119 // old bidder exist
120 if(oldBidder || oldBidder_accId)
122 std::ostringstream msgAuctionOutbiddedSubject;
123 msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED;
125 if (oldBidder && !_player)
126 oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, AHBplayerGUID, newPrice, auction->GetAuctionOutBid(), auction->item_template);
128 if (oldBidder && _player)
129 oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
131 WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
135 //this function sends mail, when auction is cancelled to old bidder
136 void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction )
138 uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
139 Player *bidder = objmgr.GetPlayer(bidder_guid);
141 uint32 bidder_accId = 0;
142 if(!bidder)
143 bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
145 // bidder exist
146 if(bidder || bidder_accId)
148 std::ostringstream msgAuctionCancelledSubject;
149 msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
151 WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
155 //this void creates new auction and adds auction to some auctionhouse
156 void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
158 CHECK_PACKET_SIZE(recv_data,8+8+4+4+4);
160 uint64 auctioneer, item;
161 uint32 etime, bid, buyout;
162 recv_data >> auctioneer >> item;
163 recv_data >> bid >> buyout >> etime;
164 Player *pl = GetPlayer();
166 if (!item || !bid || !etime)
167 return; //check for cheaters
169 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
170 if (!pCreature)
172 sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
173 return;
176 AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction());
177 if(!auctionHouseEntry)
179 sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer)) );
180 return;
184 // client send time in minutes, convert to common used sec time
185 etime *= MINUTE;
187 // client understand only 3 auction time
188 switch(etime)
190 case 1*MIN_AUCTION_TIME:
191 case 2*MIN_AUCTION_TIME:
192 case 4*MIN_AUCTION_TIME:
193 break;
194 default:
195 return;
198 // remove fake death
199 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
200 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
202 Item *it = pl->GetItemByGuid( item );
203 //do not allow to sell already auctioned items
204 if(auctionmgr.GetAItem(GUID_LOPART(item)))
206 sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item));
207 SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
208 return;
210 // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
211 if(!it)
213 SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND);
214 return;
217 if(!it->CanBeTraded())
219 SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
220 return;
223 if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION))
225 SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
226 return;
229 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
231 //we have to take deposit :
232 uint32 deposit = auctionmgr.GetAuctionDeposit( auctionHouseEntry, etime, it );
233 if ( pl->GetMoney() < deposit )
235 SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY);
236 return;
239 if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
241 sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
242 GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount());
245 pl->ModifyMoney( -int32(deposit) );
247 uint32 auction_time = uint32(etime * sWorld.getRate(RATE_AUCTION_TIME));
249 AuctionEntry *AH = new AuctionEntry;
250 AH->Id = objmgr.GenerateAuctionID();
251 if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
252 AH->auctioneer = 23442;
253 else
254 AH->auctioneer = GUID_LOPART(auctioneer);
255 AH->item_guidlow = GUID_LOPART(item);
256 AH->item_template = it->GetEntry();
257 AH->owner = pl->GetGUIDLow();
258 AH->startbid = bid;
259 AH->bidder = 0;
260 AH->bid = 0;
261 AH->buyout = buyout;
262 AH->expire_time = time(NULL) + auction_time;
263 AH->deposit = deposit;
264 AH->auctionHouseEntry = auctionHouseEntry;
266 sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId());
267 auctionHouse->AddAuction(AH);
269 auctionmgr.AddAItem(it);
270 pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true);
272 CharacterDatabase.BeginTransaction();
273 it->DeleteFromInventoryDB();
274 it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
275 AH->SaveToDB();
276 pl->SaveInventoryAndGoldToDB();
277 CharacterDatabase.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);
287 uint64 auctioneer;
288 uint32 auctionId;
289 uint32 price;
290 recv_data >> auctioneer;
291 recv_data >> auctionId >> price;
293 if (!auctionId || !price)
294 return; //check for cheaters
296 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
297 if (!pCreature)
299 sLog.outDebug( "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
300 return;
303 // remove fake death
304 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
305 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
307 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
309 AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
310 Player *pl = GetPlayer();
312 if( !auction || auction->owner == pl->GetGUIDLow() )
314 //you cannot bid your own auction:
315 SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR );
316 return;
319 // impossible have online own another character (use this for speedup check in case online owner)
320 Player* auction_owner = objmgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER));
321 if( !auction_owner && objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId())
323 //you cannot bid your another character auction:
324 SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR );
325 return;
328 // cheating
329 if(price <= auction->bid)
330 return;
332 // price too low for next bid if not buyout
333 if ((price < auction->buyout || auction->buyout == 0) &&
334 price < auction->bid + auction->GetAuctionOutBid())
336 //auction has already higher bid, client tests it!
337 return;
340 if (price > pl->GetMoney())
342 //you don't have enought money!, client tests!
343 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
344 return;
347 if ((price < auction->buyout) || (auction->buyout == 0))
349 if (auction->bidder > 0)
351 if ( auction->bidder == pl->GetGUIDLow() )
353 pl->ModifyMoney( -int32(price - auction->bid));
355 else
357 // mail to last bidder and return money
358 SendAuctionOutbiddedMail( auction , price );
359 pl->ModifyMoney( -int32(price) );
362 else
364 pl->ModifyMoney( -int32(price) );
366 auction->bidder = pl->GetGUIDLow();
367 auction->bid = price;
368 GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
370 // after this update we should save player's money ...
371 CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
373 SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 );
375 else
377 //buyout:
378 if (pl->GetGUIDLow() == auction->bidder )
380 pl->ModifyMoney(-int32(auction->buyout - auction->bid));
382 else
384 pl->ModifyMoney(-int32(auction->buyout));
385 if ( auction->bidder ) //buyout for bidded auction ..
387 SendAuctionOutbiddedMail( auction, auction->buyout );
390 auction->bidder = pl->GetGUIDLow();
391 auction->bid = auction->buyout;
392 GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
394 auctionmgr.SendAuctionSalePendingMail( auction );
395 auctionmgr.SendAuctionSuccessfulMail( auction );
396 auctionmgr.SendAuctionWonMail( auction );
398 SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
400 auctionmgr.RemoveAItem(auction->item_guidlow);
401 auctionHouse->RemoveAuction(auction->Id);
402 auction->DeleteFromDB();
404 delete auction;
406 CharacterDatabase.BeginTransaction();
407 pl->SaveInventoryAndGoldToDB();
408 CharacterDatabase.CommitTransaction();
411 //this void is called when auction_owner cancels his auction
412 void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
414 CHECK_PACKET_SIZE(recv_data,8+4);
416 uint64 auctioneer;
417 uint32 auctionId;
418 recv_data >> auctioneer;
419 recv_data >> auctionId;
420 //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId);
422 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
423 if (!pCreature)
425 sLog.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
426 return;
429 // remove fake death
430 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
431 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
433 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
435 AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
436 Player *pl = GetPlayer();
438 if (auction && auction->owner == pl->GetGUIDLow())
440 Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
441 if (pItem)
443 if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid
445 uint32 auctionCut = auction->GetAuctionCut();
446 if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed
447 return;
448 //some auctionBidderNotification would be needed, but don't know that parts..
449 SendAuctionCancelledToBidderMail( auction );
450 pl->ModifyMoney( -int32(auctionCut) );
452 // Return the item by mail
453 std::ostringstream msgAuctionCanceledOwner;
454 msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
456 MailItemsInfo mi;
457 mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
459 // item will deleted or added to received mail list
460 WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
462 else
464 sLog.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->item_guidlow);
465 SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR );
466 return;
469 else
471 SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR );
472 //this code isn't possible ... maybe there should be assert
473 sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId );
474 return;
477 //inform player, that auction is removed
478 SendAuctionCommandResult( auction->Id, AUCTION_CANCEL, AUCTION_OK );
479 // Now remove the auction
480 CharacterDatabase.BeginTransaction();
481 auction->DeleteFromDB();
482 pl->SaveInventoryAndGoldToDB();
483 CharacterDatabase.CommitTransaction();
484 auctionmgr.RemoveAItem( auction->item_guidlow );
485 auctionHouse->RemoveAuction( auction->Id );
486 delete auction;
489 //called when player lists his bids
490 void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
492 CHECK_PACKET_SIZE(recv_data,8+4+4);
494 uint64 guid; //NPC guid
495 uint32 listfrom; //page of auctions
496 uint32 outbiddedCount; //count of outbidded auctions
498 recv_data >> guid;
499 recv_data >> listfrom; // not used in fact (this list not have page control in client)
500 recv_data >> outbiddedCount;
501 if (recv_data.size() != (16 + outbiddedCount * 4 ))
503 sLog.outError("Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(),(16 + outbiddedCount * 4 ));
504 outbiddedCount = 0;
507 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
508 if (!pCreature)
510 sLog.outDebug( "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
511 return;
514 // remove fake death
515 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
516 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
518 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
520 WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) );
521 Player *pl = GetPlayer();
522 data << (uint32) 0; //add 0 as count
523 uint32 count = 0;
524 uint32 totalcount = 0;
525 while ( outbiddedCount > 0) //add all data, which client requires
527 --outbiddedCount;
528 uint32 outbiddedAuctionId;
529 recv_data >> outbiddedAuctionId;
530 AuctionEntry * auction = auctionHouse->GetAuction( outbiddedAuctionId );
531 if ( auction && auction->BuildAuctionInfo(data))
533 ++totalcount;
534 ++count;
538 auctionHouse->BuildListBidderItems(data,pl,count,totalcount);
539 data.put<uint32>( 0, count ); // add count to placeholder
540 data << totalcount;
541 data << (uint32)300; //unk 2.3.0
542 SendPacket(&data);
545 //this void sends player info about his auctions
546 void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
548 CHECK_PACKET_SIZE(recv_data,8+4);
550 uint32 listfrom;
551 uint64 guid;
553 recv_data >> guid;
554 recv_data >> listfrom; // not used in fact (this list not have page control in client)
556 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
557 if (!pCreature)
559 sLog.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
560 return;
563 // remove fake death
564 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
565 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
567 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
569 WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4) );
570 data << (uint32) 0; // amount place holder
572 uint32 count = 0;
573 uint32 totalcount = 0;
575 auctionHouse->BuildListOwnerItems(data,_player,count,totalcount);
576 data.put<uint32>(0, count);
577 data << (uint32) totalcount;
578 data << (uint32) 0;
579 SendPacket(&data);
582 //this void is called when player clicks on search button
583 void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
585 CHECK_PACKET_SIZE(recv_data,8+4+1+1+1+4+4+4+4+1);
587 std::string searchedname;
588 uint8 levelmin, levelmax, usable;
589 uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
590 uint64 guid;
592 recv_data >> guid;
593 recv_data >> listfrom; // start, used for page control listing by 50 elements
594 recv_data >> searchedname;
596 // recheck with known string size
597 CHECK_PACKET_SIZE(recv_data,8+4+(searchedname.size()+1)+1+1+4+4+4+4+1);
599 recv_data >> levelmin >> levelmax;
600 recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
601 recv_data >> quality >> usable;
603 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
604 if (!pCreature)
606 sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
607 return;
610 // remove fake death
611 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
612 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
614 AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
616 //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);
618 WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) );
619 uint32 count = 0;
620 uint32 totalcount = 0;
621 data << (uint32) 0;
623 // converting string that we try to find to lower case
624 std::wstring wsearchedname;
625 if(!Utf8toWStr(searchedname,wsearchedname))
626 return;
628 wstrToLower(wsearchedname);
630 auctionHouse->BuildListAuctionItems(data,_player,
631 wsearchedname, listfrom, levelmin, levelmax, usable,
632 auctionSlotID, auctionMainCategory, auctionSubCategory, quality,
633 count,totalcount);
635 data.put<uint32>(0, count);
636 data << (uint32) totalcount;
637 data << (uint32) 300; // unk 2.3.0 const?
638 SendPacket(&data);
641 void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data )
643 sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
644 recv_data.hexlike();
646 uint32 count = 0;
648 WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
649 data << uint32(count); // count
650 /*for(uint32 i = 0; i < count; ++i)
652 data << ""; // string
653 data << ""; // string
654 data << uint32(0);
655 data << uint32(0);
656 data << float(0);
658 SendPacket(&data);