void AuctionHouse::SendBidListPacket(Player* plr, WorldPacket* packet) { uint32 count = 0; WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, 1024); data << uint32(0); // Placeholder Auction* auct; auctionLock.AcquireReadLock(); std::unordered_map<uint32, Auction*>::iterator itr = auctions.begin(); for (; itr != auctions.end(); ++itr) { auct = itr->second; if (auct->HighestBidder == plr->GetGUID()) { if (auct->Deleted) continue; auct->AddToPacket(data); (*(uint32*)&data.contents()[0])++; ++count; } } data << count; auctionLock.ReleaseReadLock(); plr->GetSession()->SendPacket(&data); }
void AuctionHouse::SendOwnerListPacket(Player * plr, WorldPacket * packet) { uint32 count = 0; WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, 1024); data << uint32(0); // Placeholder Auction * auct; auctionLock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Auction*>::iterator itr = auctions.begin(); for(; itr != auctions.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 auctionLock.ReleaseReadLock(); plr->GetSession()->SendPacket(&data); }
void AuctionHouse::SendOwnerListPacket(Player* plr, WorldPacket* packet) { uint32 count = 0; uint32 totalcount = 0; WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4 + 4 + 4)); data << uint32(0); // Placeholder Auction* auct; auctionLock.AcquireReadLock(); std::unordered_map<uint32, Auction*>::iterator itr = auctions.begin(); for (; itr != auctions.end(); ++itr) { auct = itr->second; if (auct->Owner == plr->GetGUID()) { if (auct->Deleted) continue; if (auct->BuildAuctionInfo(data)) ++count; ++totalcount; } } data.put<uint32>(0, count); data << uint32(totalcount); data << uint32(0); auctionLock.ReleaseReadLock(); plr->GetSession()->SendPacket(&data); }
void AuctionHouse::UpdateOwner(uint32 oldGuid, uint32 newGuid) { auctionLock.AcquireWriteLock(); HM_NAMESPACE::hash_map<uint32, Auction*>::iterator itr = auctions.begin(); Auction * auction; for(; itr != auctions.end(); ++itr) { auction = itr->second; if(auction->Owner == oldGuid) auction->Owner = newGuid; if(auction->HighestBidder == oldGuid) { auction->HighestBidder = newGuid; auction->UpdateInDB(); } } auctionLock.ReleaseWriteLock(); }
void AuctionHouse::UpdateItemOwnerships(uint32 oldGuid, uint32 newGuid) { Auction * auct; auctionLock.AcquireWriteLock(); HM_NAMESPACE::hash_map<uint32, Auction*>::iterator itr = auctions.begin(); for(; itr != auctions.end(); itr++) { auct = itr->second; if(auct->Owner == oldGuid) { auct->Owner = newGuid; // Don't save, we take care of this in char rename all at once. Less queries. } if(auct->HighestBidder == oldGuid) { auct->HighestBidder = newGuid; auct->UpdateInDB(); } } auctionLock.ReleaseWriteLock(); }
void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { if (!_player->IsInWorld()) { return; } uint64 guid,item; uint32 bid, buyout, etime, unk1, unk2; // etime is in minutes recv_data >> guid >> unk1 >> item; recv_data >> unk2; recv_data >> bid >> buyout >> etime; Creature * pCreature = _player->GetMapMgr()->GetCreature( guid ); if( !pCreature || !pCreature->auctionHouse ) return; // NPC doesnt exist or isnt an auctioneer // Get item Item * pItem = _player->GetItemInterface()->GetItemByGUID(item); if( !pItem || pItem->IsSoulbound() || pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_CONJURED ) ) { sStackWolrdPacket( data,SMSG_AUCTION_COMMAND_RESULT, 50); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_ITEM); SendPacket(&data); return; }; AuctionHouse * ah = pCreature->auctionHouse; uint32 item_worth = pItem->GetProto()->SellPrice * pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT); uint32 item_deposit = (uint32)(item_worth * ah->deposit_percent) * (uint32)(etime / 240.0f); // deposit is per 4 hours if (_player->GetGold() < item_deposit) // player cannot afford deposit { sStackWolrdPacket( data,SMSG_AUCTION_COMMAND_RESULT, 50); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_MONEY); SendPacket(&data); return; } pItem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(item, false); if (!pItem){ sStackWolrdPacket( data, SMSG_AUCTION_COMMAND_RESULT, 50); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_ITEM); SendPacket(&data); return; }; if( pItem->IsInWorld() ) { pItem->RemoveFromWorld(); } pItem->SetOwner(NULL); pItem->m_isDirty = true; pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); // Create auction Auction * auct = new Auction; auct->BuyoutPrice = buyout; auct->ExpiryTime = (uint32)UNIXTIME + (etime * 60); auct->StartingPrice = bid; auct->HighestBid = 0; auct->HighestBidder = 0; // hm auct->Id = sAuctionMgr.GenerateAuctionId(); auct->Owner = _player->GetLowGUID(); auct->pItem = pItem; auct->Deleted = false; auct->DeletedReason = 0; auct->DepositAmount = item_deposit; // remove deposit _player->ModGold(-(int32)item_deposit); // Add and save auction to DB ah->AddAuction(auct); auct->SaveToDB(ah->GetID()); // Send result packet sStackWolrdPacket( data,SMSG_AUCTION_COMMAND_RESULT, 50); data << auct->Id; data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_NONE); SendPacket(&data); }
void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) { if(!_player->IsInWorld()) { return; } uint64 guid; recv_data >> guid; uint32 auction_id, price; recv_data >> auction_id >> price; Creature * pCreature = _player->GetMapMgr()->GetCreature( guid ); if(!pCreature || !pCreature->auctionHouse) { return; } // Find Item AuctionHouse * ah = pCreature->auctionHouse; Auction * auct = ah->GetAuction(auction_id); if(auct == 0 || !auct->Owner || !_player) { SendAuctionPlaceBidResultPacket(0, AUCTION_ERROR_INTERNAL); return; } if(auct->Owner == _player->GetGUID()) { SendAuctionPlaceBidResultPacket(0, AUCTION_ERROR_BID_OWN_AUCTION); return; } if(auct->HighestBid > price && price != auct->BuyoutPrice) { //HACK: Don't know the correct error code... SendAuctionPlaceBidResultPacket(0, AUCTION_ERROR_INTERNAL); return; } if(_player->GetGold() < price) { SendAuctionPlaceBidResultPacket(0, AUCTION_ERROR_MONEY); return; } _player->ModGold( -((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(AUCTION, ah->GetID(), auct->HighestBidder, subject, "", auct->HighestBid, 0, 0, MAIL_STATIONERY_AUCTION ); // Do not send out bid notification, when current highest bidder and new bidder are the same player.. if(auct->HighestBidder != (uint32)_player->GetLowGUID()) ah->SendAuctionOutBidNotificationPacket(auct, _player->GetGUID(), price); } if(auct->BuyoutPrice == price) { auct->HighestBidder = _player->GetLowGUID(); auct->HighestBid = price; // we used buyout on the item. ah->QueueDeletion(auct, AUCTION_REMOVE_WON); SendAuctionPlaceBidResultPacket(auct->Id, AUCTION_ERROR_NONE); ah->SendAuctionBuyOutNotificationPacket(auct); } else { // update most recent bid auct->HighestBidder = _player->GetLowGUID(); auct->HighestBid = price; auct->UpdateInDB(); SendAuctionPlaceBidResultPacket(auct->Id, AUCTION_ERROR_NONE); } }
void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) { CHECK_INWORLD_RETURN; uint64 guid; recv_data >> guid; uint32 auction_id, price; recv_data >> auction_id >> price; Creature* pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(!pCreature || !pCreature->auctionHouse || price == 0) return; // Find Item AuctionHouse * ah = pCreature->auctionHouse; Auction * auct = ah->GetAuction(auction_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.DeliverMessage(MAILTYPE_AUCTION, ah->GetID(), auct->HighestBidder, subject, "", auct->HighestBid, 0, 0, STATIONERY_AUCTION, true); } if(auct->BuyoutPrice == price) { auct->HighestBidder = _player->GetLowGUID(); auct->HighestBid = price; // we used buyout on the item. ah->QueueDeletion(auct, AUCTION_REMOVE_WON); // send response packet WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 12); data << auct->Id << uint32(AUCTION_BID) << uint32(0); SendPacket(&data); } else { // update most recent bid auct->HighestBidder = _player->GetLowGUID(); auct->HighestBid = price; auct->UpdateInDB(); // send response packet WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 12); data << auct->Id << uint32(AUCTION_BID) << uint32(0); SendPacket(&data); } }
void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { if (!_player->IsInWorld()) return; uint64 guid,item; uint32 bid, buyout, etime, unk1, unk2; // etime is in minutes recv_data >> guid >> unk1 >> item; recv_data >> unk2; recv_data >> bid >> buyout >> etime; Creature * pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if( !pCreature || !pCreature->auctionHouse ) return; // NPC doesn't exist or isn't an auctioneer // Get item Item * pItem = _player->GetItemInterface()->GetItemByGUID(item); if( !pItem || pItem->IsSoulbound() || pItem->IsConjured() ) { WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 8); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_ITEM); SendPacket(&data); return; }; if (m_gmData->rank > RANK_NO_RANK && m_gmData->rank < RANK_COADMIN) { SystemMessage("GMs cannot post auctions"); WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 8); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_ITEM); SendPacket(&data); return; }; AuctionHouse * ah = pCreature->auctionHouse; uint32 item_worth = pItem->GetProto()->SellPrice * pItem->GetStackCount(); uint32 item_deposit = (uint32)(item_worth * ah->deposit_percent) * (uint32)(etime / 240.0f); // deposit is per 4 hours if( !_player->HasGold(item_deposit) ) // player cannot afford deposit { WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 8); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_MONEY); SendPacket(&data); return; } pItem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(item, false); if (!pItem){ WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 8); data << uint32(0); data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_ITEM); SendPacket(&data); return; }; if( pItem->IsInWorld() ) { pItem->RemoveFromWorld(); } pItem->SetOwner(NULL); pItem->m_isDirty = true; pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); // Create auction Auction * auct = new Auction; auct->BuyoutPrice = buyout; auct->ExpiryTime = (uint32)UNIXTIME + (etime * 60); auct->HighestBid = bid; auct->HighestBidder = 0; // hm auct->Id = sAuctionMgr.GenerateAuctionId(); auct->Owner = _player->GetLowGUID(); auct->pItem = pItem; auct->Deleted = false; auct->DeletedReason = 0; auct->DepositAmount = item_deposit; // remove deposit _player->ModGold( -(int32)item_deposit ); // Add and save auction to DB ah->AddAuction(auct); auct->SaveToDB(ah->GetID()); // Send result packet WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 8); data << auct->Id; data << uint32(AUCTION_CREATE); data << uint32(AUCTION_ERROR_NONE); SendPacket(&data); }
void WorldSession::HandleAuctionSellItem(WorldPacket& recv_data) { CHECK_INWORLD_RETURN uint64 auctioneer, bid, buyout; uint32 itemsCount, etime; recv_data >> auctioneer; recv_data >> itemsCount; uint64 itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot uint32 count[MAX_AUCTION_ITEMS]; for (uint32 i = 0; i < itemsCount; ++i) { recv_data >> itemGUIDs[i]; recv_data >> count[i]; if (!itemGUIDs[i] || !count[i] || count[i] > 1000) return; } recv_data >> bid; recv_data >> buyout; recv_data >> etime; if (!bid || !etime) return; Creature* pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(auctioneer)); if (!pCreature || !pCreature->auctionHouse) return; // NPC doesn't exist or isn't an auctioneer AuctionHouse* ah = pCreature->auctionHouse; etime *= MINUTE; switch (etime) { case 1 * MIN_AUCTION_TIME: case 2 * MIN_AUCTION_TIME: case 4 * MIN_AUCTION_TIME: break; default: return; } Item* items[MAX_AUCTION_ITEMS]; uint32 finalCount = 0; for (uint32 i = 0; i < itemsCount; ++i) { Item* item = _player->GetItemInterface()->GetItemByGUID(itemGUIDs[i]); if (!item) { _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_ITEM_NOT_FOUND); return; } items[i] = item; finalCount += count[i]; } if (!finalCount) { _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_DATABASE_ERROR); return; } for (uint32 i = 0; i < itemsCount; ++i) { Item* item = items[i]; if (item->GetStackCount() < finalCount) { _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_DATABASE_ERROR); return; } } for (uint32 i = 0; i < itemsCount; ++i) { Item* item = items[i]; uint32 auctionTime = uint32(etime); AuctionHouse* ah = pCreature->auctionHouse; uint32 item_worth = item->GetProto()->SellPrice * item->GetStackCount(); uint32 item_deposit = (uint32)(item_worth * ah->deposit_percent) * (uint32)(etime / 240.0f); // deposit is per 4 hours if (!_player->HasGold((uint64)item_deposit)) { _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_NOT_ENOUGHT_MONEY); return; } _player->TakeGold(-int32(item_deposit)); item = _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(itemGUIDs[i], false); if (!item) { _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_ITEM_NOT_FOUND); return; }; if (item->IsInWorld()) { item->RemoveFromWorld(); } item->SetOwner(NULL); item->m_isDirty = true; item->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); // Create auction Auction* auct = new Auction; auct->BuyoutPrice = buyout; auct->ExpiryTime = (uint32)UNIXTIME + (etime * 60); auct->StartingPrice = bid; auct->HighestBid = 0; auct->HighestBidder = 0; // hm auct->Id = sAuctionMgr.GenerateAuctionId(); auct->Owner = _player->GetLowGUID(); auct->pItem = item; auct->Deleted = false; auct->DeletedReason = 0; auct->DepositAmount = item_deposit; // Add and save auction to DB ah->AddAuction(auct); auct->SaveToDB(ah->GetID()); // Send result packet _player->SendAuctionCommandResult(NULL, AUCTION_CREATE, ERR_AUCTION_OK); } ah->SendOwnerListPacket(_player, &recv_data); }
int main(){ Auction auc; Item itf; auc.insert("car", 10); auc.insert("card", 37); auc.insert("coffee", 23); auc.start("car"); auc.start("coffee"); auc.start("abc"); auc.bid("angie", "abc", 5); auc.bid("angie", "car", 5); auc.bid("grant", "car", 13); auc.bid("grant", "car", 11); auc.bid("mary", "coffee", 20); auc.bid("john", "coffee", 2121); auc.query("car", itf); auc.query("card", itf); auc.query("coffee", itf); auc.query("abc", itf); auc.end("car"); auc.end("card"); auc.end("coffee"); auc.end("abc"); auc.query("car", itf); auc.query("card", itf); auc.query("coffee", itf); auc.query("abc", itf); auc.del("car"); auc.del("abc"); auc.query("car", itf); auc.query("card", itf); auc.query("coffee", itf); auc.query("abc", itf); }