diff --git a/sql/characters.sql b/sql/characters.sql index 4837a0b4e..fefd2a5f1 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_11299_02_characters_pet_aura` bit(1) default NULL + `required_11391_01_characters_auction` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/11391_01_characters_auction.sql b/sql/updates/11391_01_characters_auction.sql new file mode 100644 index 000000000..ac2280ce6 --- /dev/null +++ b/sql/updates/11391_01_characters_auction.sql @@ -0,0 +1,4 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_11299_02_characters_pet_aura required_11391_01_characters_auction bit; + +ALTER TABLE `auction` + ADD COLUMN `moneyTime` BIGINT(40) DEFAULT '0' NOT NULL AFTER `time`; diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 27af70a8e..1b92368a6 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -67,47 +67,100 @@ void WorldSession::SendAuctionHello(Unit* unit) } // call this method when player bids, creates, or deletes auction -void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError ) +void WorldSession::SendAuctionCommandResult(AuctionEntry *auc, AuctionAction Action, AuctionError ErrorCode, InventoryResult invError ) { WorldPacket data( SMSG_AUCTION_COMMAND_RESULT, 16 ); - data << uint32(auctionId); + data << uint32(auc ? auc->Id : 0); data << uint32(Action); data << uint32(ErrorCode); - if ( !ErrorCode && Action ) - data << uint32(bidError); // when bid, then send 0, once... + + switch(ErrorCode) + { + case AUCTION_OK: + if(Action == AUCTION_BID_PLACED) + data << uint32(auc->GetAuctionOutBid()); // new AuctionOutBid? + break; + case AUCTION_ERR_INVENTORY: + data << uint32(invError); + break; + case AUCTION_ERR_HIGHER_BID: + data << ObjectGuid(HIGHGUID_PLAYER,auc->bidder);// new bidder guid + data << uint32(auc->bid); // new bid + data << uint32(auc->GetAuctionOutBid()); // new AuctionOutBid? + break; + default: + break; + } + SendPacket(&data); } // this function sends notification, if bidder is online -void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctionId, ObjectGuid bidderGuid, uint32 bidSum, uint32 diff, uint32 item_template) +void WorldSession::SendAuctionBidderNotification(AuctionEntry* auction) { WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4)); - data << uint32(location); - data << uint32(auctionId); - data << bidderGuid; - data << uint32(bidSum); - data << uint32(diff); - data << uint32(item_template); - data << uint32(0); + data << uint32(auction->GetHouseId()); + data << uint32(auction->Id); + data << ObjectGuid(HIGHGUID_PLAYER, auction->bidder); + + // if 0, client shows ERR_AUCTION_WON_S, else ERR_AUCTION_OUTBID_S + data << uint32(auction->moneyDeliveryTime ? 0 : auction->bid); + data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid? + data << uint32(auction->itemTemplate); + + Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow); + uint32 randomId = item ? item->GetItemRandomPropertyId() : 0; + + data << uint32(randomId); // random property (value > 0) or suffix (value < 0) + SendPacket(&data); } // this void causes on client to display: "Your auction sold" -void WorldSession::SendAuctionOwnerNotification( AuctionEntry* auction) +void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) { WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4)); data << uint32(auction->Id); - data << uint32(auction->bid); - data << uint32(0); // unk - data << uint32(0); // unk - data << uint32(0); // unk - data << uint32(auction->item_template); - data << uint32(0); // unk + data << uint32(auction->bid); // if 0, client shows ERR_AUCTION_EXPIRED_S, else ERR_AUCTION_SOLD_S (works only when guid==0) + data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid? + + ObjectGuid guid = ObjectGuid(); + if(!auction->moneyDeliveryTime) // not sold yet + guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder);// bidder==0 and moneyDeliveryTime==0 for expired auctions, so it will show error message properly + + // if guid!=0, client updates auctions with new bid, outbid and bidderGuid, else it shows error messages as described above + data << guid; // bidder guid + data << uint32(auction->itemTemplate); // item entry + + Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow); + uint32 randomId = item ? item->GetItemRandomPropertyId() : 0; + + data << uint32(randomId); // random property (value > 0) or suffix (value < 0) + + float timeLeft = float(auction->moneyDeliveryTime - time(NULL)) / float(DAY); + + data << float(timeLeft); // time till money arrive? only used if bid != 0 + + SendPacket(&data); +} + +// shows ERR_AUCTION_REMOVED_S +void WorldSession::SendAuctionRemovedNotification(AuctionEntry* auction) +{ + WorldPacket data(SMSG_AUCTION_REMOVED_NOTIFICATION, (3*4)); + data << uint32(auction->Id); + data << uint32(auction->itemTemplate); + + Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow); + uint32 randomId = item ? item->GetItemRandomPropertyId() : 0; + + data << uint32(randomId); // random property (value > 0) or suffix (value < 0) + SendPacket(&data); } // this function sends mail to old bidder -void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice) +void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction) { ObjectGuid oldBidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder); Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid); @@ -120,12 +173,10 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri if(oldBidder || oldBidder_accId) { std::ostringstream msgAuctionOutbiddedSubject; - msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED << ":0:0"; + msgAuctionOutbiddedSubject << auction->itemTemplate << ":0:" << AUCTION_OUTBIDDED << ":0:0"; if (oldBidder) - oldBidder->GetSession()->SendAuctionBidderNotification( - auction->GetHouseId(), auction->Id, _player->GetObjectGuid(), - newPrice, auction->GetAuctionOutBid(), auction->item_template); + oldBidder->GetSession()->SendAuctionBidderNotification(auction); MailDraft(msgAuctionOutbiddedSubject.str(), "") // TODO: fix body .SetMoney(auction->bid) @@ -147,7 +198,10 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction ) if(bidder || bidder_accId) { std::ostringstream msgAuctionCancelledSubject; - msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0"; + msgAuctionCancelledSubject << auction->itemTemplate << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0"; + + if(bidder) + bidder->GetSession()->SendAuctionRemovedNotification(auction); MailDraft(msgAuctionCancelledSubject.str(), "") // TODO: fix body .SetMoney(auction->bid) @@ -193,17 +247,33 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) DEBUG_LOG("WORLD: HandleAuctionSellItem"); ObjectGuid auctioneerGuid; - ObjectGuid itemGuid; - uint32 etime, bid, buyout; + uint32 etime, bid, buyout, itemCount; + std::vector guids; + std::vector stackSizes; + recv_data >> auctioneerGuid; - recv_data.read_skip(); // const 1? - recv_data >> itemGuid; - recv_data.read_skip(); // stack size + recv_data >> itemCount; + + if(itemCount > MAX_BAG_SIZE * 5) + { + recv_data.rpos(recv_data.wpos()); // should not happen + return; + } + + guids.resize(itemCount); + stackSizes.resize(itemCount); + + for(uint32 i = 0; i < itemCount; ++i) + { + recv_data >> guids[i]; // item guid + recv_data >> stackSizes[i]; // stack size + } + recv_data >> bid; recv_data >> buyout; recv_data >> etime; - if (itemGuid.IsEmpty() || !bid || !etime) + if (!bid || !etime) return; // check for cheaters Player *pl = GetPlayer(); @@ -233,81 +303,105 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - Item *it = pl->GetItemByGuid(itemGuid); - // do not allow to sell already auctioned items - if (sAuctionMgr.GetAItem(itemGuid.GetCounter())) + for(uint32 i = 0; i < itemCount; ++i) { - sLog.outError("AuctionError, %s is sending %s, but item is already in another auction", pl->GetGuidStr().c_str(), itemGuid.GetString().c_str()); - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); - return; + ObjectGuid itemGuid = guids[i]; + + if(itemGuid.IsEmpty()) + continue; + + uint32 stackSize = stackSizes[i]; + + Item *it = pl->GetItemByGuid(itemGuid); + + // do not allow to sell already auctioned items + if (sAuctionMgr.GetAItem(itemGuid.GetCounter())) + { + sLog.outError("AuctionError, %s is sending %s, but item is already in another auction", pl->GetGuidStr().c_str(), itemGuid.GetString().c_str()); + SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); + continue; + } + + // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) + if(!it) + { + SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); + continue; + } + + if(!it->CanBeTraded()) + { + SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); + continue; + } + + if ((it->GetProto()->Flags & ITEM_FLAG_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) + { + SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); + continue; + } + + // check money for deposit + uint32 deposit = AuctionHouseMgr::GetAuctionDeposit( auctionHouseEntry, etime, it ); + if ( pl->GetMoney() < deposit ) + { + SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_NOT_ENOUGH_MONEY); + continue; + } + + if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE) ) + { + sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", + GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); + } + + if(stackSize == 0) + stackSize = 1; + + if(stackSize > it->GetMaxStackCount()) // too big stack size + stackSize = it->GetMaxStackCount(); + + if(!pl->HasItemCount(it->GetEntry(), stackSize)) // not enough items + continue; + + Item *newItem = it->CloneItem(stackSize, pl); + + pl->DestroyItemCount(it, stackSize, true); + + pl->ModifyMoney( -int32(deposit) ); + + uint32 auction_time = uint32(etime * sWorld.getConfig(CONFIG_FLOAT_RATE_AUCTION_TIME)); + + AuctionEntry *AH = new AuctionEntry; + AH->Id = sObjectMgr.GenerateAuctionID(); + AH->itemGuidLow = newItem->GetObjectGuid().GetCounter(); + AH->itemTemplate = newItem->GetEntry(); + AH->owner = pl->GetGUIDLow(); + AH->startbid = bid; + AH->bidder = 0; + AH->bid = 0; + AH->buyout = buyout; + AH->expireTime = time(NULL) + auction_time; + AH->moneyDeliveryTime = 0; + AH->deposit = deposit; + AH->auctionHouseEntry = auctionHouseEntry; + + DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", + itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, auction_time, AH->GetHouseId()); + auctionHouse->AddAuction(AH); + + sAuctionMgr.AddAItem(newItem); + + CharacterDatabase.BeginTransaction(); + newItem->SaveToDB(); + AH->SaveToDB(); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + + SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK); + + GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } - // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) - if(!it) - { - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND); - return; - } - - if(!it->CanBeTraded()) - { - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); - return; - } - - if ((it->GetProto()->Flags & ITEM_FLAG_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) - { - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); - return; - } - - //we have to take deposit : - uint32 deposit = AuctionHouseMgr::GetAuctionDeposit( auctionHouseEntry, etime, it ); - if ( pl->GetMoney() < deposit ) - { - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); - return; - } - - if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE) ) - { - sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", - GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); - } - - pl->ModifyMoney( -int32(deposit) ); - - uint32 auction_time = uint32(etime * sWorld.getConfig(CONFIG_FLOAT_RATE_AUCTION_TIME)); - - AuctionEntry *AH = new AuctionEntry; - AH->Id = sObjectMgr.GenerateAuctionID(); - AH->item_guidlow = itemGuid.GetCounter(); - AH->item_template = it->GetEntry(); - AH->owner = pl->GetGUIDLow(); - AH->startbid = bid; - AH->bidder = 0; - AH->bid = 0; - AH->buyout = buyout; - AH->expire_time = time(NULL) + auction_time; - AH->deposit = deposit; - AH->auctionHouseEntry = auctionHouseEntry; - - DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", - itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, auction_time, AH->GetHouseId()); - auctionHouse->AddAuction(AH); - - sAuctionMgr.AddAItem(it); - pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true); - - CharacterDatabase.BeginTransaction(); - it->DeleteFromInventoryDB(); - it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone - AH->SaveToDB(); - pl->SaveInventoryAndGoldToDB(); - CharacterDatabase.CommitTransaction(); - - SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); - - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } // this function is called when client bids or buys out auction @@ -335,14 +429,13 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if( !auction || auction->owner == pl->GetGUIDLow() ) { // you cannot bid your own auction: - SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); + SendAuctionCommandResult( NULL, AUCTION_BID_PLACED, AUCTION_ERR_BID_OWN ); return; } @@ -353,7 +446,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if (!auction_owner && sObjectMgr.GetPlayerAccountIdByGUID(ownerGuid) == pl->GetSession()->GetAccountId()) { // you cannot bid your another character auction: - SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); + SendAuctionCommandResult( NULL, AUCTION_BID_PLACED, AUCTION_ERR_BID_OWN ); return; } @@ -372,68 +465,61 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if (price > pl->GetMoney()) { // you don't have enough money!, client tests! - // SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); + // SendAuctionCommandResult(auction->auctionId, AUCTION_ERR_INVENTORY, EQUIP_ERR_NOT_ENOUGH_MONEY); return; } - if ((price < auction->buyout) || (auction->buyout == 0)) + if ((price < auction->buyout) || (auction->buyout == 0))// bid { - if (auction->bidder > 0) + if (pl->GetGUIDLow() == auction->bidder) { - if ( auction->bidder == pl->GetGUIDLow() ) - { - pl->ModifyMoney( -int32(price - auction->bid)); - } - else - { - // mail to last bidder and return money - SendAuctionOutbiddedMail( auction , price ); - pl->ModifyMoney( -int32(price) ); - } + pl->ModifyMoney(-int32(price - auction->bid)); } else { - pl->ModifyMoney( -int32(price) ); + pl->ModifyMoney(-int32(price)); + if (auction->bidder) // return money to old bidder if present + SendAuctionOutbiddedMail(auction); } + auction->bidder = pl->GetGUIDLow(); auction->bid = price; + + if(auction_owner) + auction_owner->GetSession()->SendAuctionOwnerNotification(auction); + GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); // after this update we should save player's money ... - CharacterDatabase.PExecute("UPDATE auction SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); + CharacterDatabase.PExecute("UPDATE auction SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); - SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 ); + SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK); } - else + else // buyout { - // buyout: - if (pl->GetGUIDLow() == auction->bidder ) + if (pl->GetGUIDLow() == auction->bidder) { pl->ModifyMoney(-int32(auction->buyout - auction->bid)); } else { pl->ModifyMoney(-int32(auction->buyout)); - if ( auction->bidder ) // buyout for bidded auction .. - { - SendAuctionOutbiddedMail( auction, auction->buyout ); - } + if (auction->bidder) // return money to old bidder if present + SendAuctionOutbiddedMail(auction); } + auction->bidder = pl->GetGUIDLow(); auction->bid = auction->buyout; + GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); - sAuctionMgr.SendAuctionSalePendingMail( auction ); - sAuctionMgr.SendAuctionSuccessfulMail( auction ); - sAuctionMgr.SendAuctionWonMail( auction ); + auction->moneyDeliveryTime = time(NULL) + HOUR; - SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); + sAuctionMgr.SendAuctionWonMail(auction); - sAuctionMgr.RemoveAItem(auction->item_guidlow); - auctionHouse->RemoveAuction(auction->Id); - auction->DeleteFromDB(); + SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK); - delete auction; + CharacterDatabase.PExecute("UPDATE auction SET moneyTime = '" UI64FMTD "', buyguid = '%u', lastbid = '%u' WHERE id = '%u'", (uint64)auction->moneyDeliveryTime, auction->bidder, auction->bid, auction->Id); } CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); @@ -467,21 +553,21 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) if (auction && auction->owner == pl->GetGUIDLow()) { - Item *pItem = sAuctionMgr.GetAItem(auction->item_guidlow); + Item *pItem = sAuctionMgr.GetAItem(auction->itemGuidLow); if (pItem) { if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); - if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed + if ( pl->GetMoney() < auctionCut ) // player doesn't have enough money, maybe message needed return; - //some auctionBidderNotification would be needed, but don't know that parts.. + SendAuctionCancelledToBidderMail( auction ); pl->ModifyMoney( -int32(auctionCut) ); } // Return the item by mail std::ostringstream msgAuctionCanceledOwner; - msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0"; + msgAuctionCanceledOwner << auction->itemTemplate << ":0:" << AUCTION_CANCELED << ":0:0"; // item will deleted or added to received mail list MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body @@ -490,32 +576,32 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) } else { - sLog.outError("Auction id: %u has nonexistent item (item guid : %u)!!!", auction->Id, auction->item_guidlow); - SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); + sLog.outError("Auction id: %u has nonexistent item (item guid : %u)!!!", auction->Id, auction->itemGuidLow); + SendAuctionCommandResult( NULL, AUCTION_REMOVED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND ); return; } } else { - SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); - //this code isn't possible ... maybe there should be ASSERT - sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId ); + SendAuctionCommandResult( NULL, AUCTION_REMOVED, AUCTION_ERR_DATABASE ); + // this code isn't possible ... maybe there should be ASSERT + sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId); return; } - //inform player, that auction is removed - SendAuctionCommandResult( auction->Id, AUCTION_CANCEL, AUCTION_OK ); + // inform player, that auction is removed + SendAuctionCommandResult(auction, AUCTION_REMOVED, AUCTION_OK ); // Now remove the auction CharacterDatabase.BeginTransaction(); auction->DeleteFromDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); - sAuctionMgr.RemoveAItem( auction->item_guidlow ); + sAuctionMgr.RemoveAItem( auction->itemGuidLow ); auctionHouse->RemoveAuction( auction->Id ); delete auction; } -//called when player lists his bids +// called when player lists his bids void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: HandleAuctionListBidderItems"); @@ -600,18 +686,18 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) auctionHouse->BuildListOwnerItems(data, _player, count, totalcount); data.put(0, count); data << uint32(totalcount); - data << uint32(0); // 2.3.0 delay for next list request? + data << uint32(300); // 2.3.0 delay for next list request? SendPacket(&data); } -//this void is called when player clicks on search button +// this void is called when player clicks on search button void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: HandleAuctionListItems"); ObjectGuid auctioneerGuid; std::string searchedname; - uint8 levelmin, levelmax, usable; + uint8 levelmin, levelmax, usable, isFull, sortCount; uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; recv_data >> auctioneerGuid; @@ -619,10 +705,15 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) recv_data >> searchedname; recv_data >> levelmin >> levelmax; - recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; - recv_data >> quality >> usable; + recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory >> quality; + recv_data >> usable >> isFull >> sortCount; - recv_data.read_skip(16); // unknown 16 bytes: 00 07 01 00 00 01 05 00 06 00 09 01 08 00 03 00 + // auction columns sorting + for(uint32 i = 0; i < sortCount; ++i) + { + recv_data.read_skip(); // column? + recv_data.read_skip(); // direction? + } AuctionHouseEntry const* auctionHouseEntry = GetCheckedAuctionHouseForAuctioneer(auctioneerGuid); if (!auctionHouseEntry) @@ -673,17 +764,14 @@ void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data ) if (!auctionHouseEntry) return; + // always return pointer + AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry); + uint32 count = 0; WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4); data << uint32(count); // count - /*for(uint32 i = 0; i < count; ++i) - { - data << ""; // string - data << ""; // string - data << uint32(0); - data << uint32(0); - data << float(0); - }*/ + auctionHouse->BuildListPendingSales(data, _player, count); + data.put(0, count); SendPacket(&data); } diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index bed04f851..db69cccef 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -76,10 +76,10 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 return uint32(deposit * sWorld.getConfig(CONFIG_FLOAT_RATE_AUCTION_DEPOSIT)); } -//does not clear ram +// does not clear ram void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) { - Item *pItem = GetAItem(auction->item_guidlow); + Item *pItem = GetAItem(auction->itemGuidLow); if(!pItem) return; @@ -127,11 +127,16 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) else if (!bidder) bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid); + ObjectGuid ownerGuid = ObjectGuid(HIGHGUID_PLAYER, auction->owner); + Player* auction_owner = sObjectMgr.GetPlayer(ownerGuid); + if(auction_owner) + auction_owner->GetSession()->SendAuctionOwnerNotification( auction ); + // receiver exist if(bidder || bidder_accId) { std::ostringstream msgAuctionWonSubject; - msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON; + msgAuctionWonSubject << auction->itemTemplate << ":0:" << AUCTION_WON; std::ostringstream msgAuctionWonBody; msgAuctionWonBody.width(16); @@ -146,7 +151,7 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) if (bidder) { - bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template); + bidder->GetSession()->SendAuctionBidderNotification(auction); // FIXME: for offline player need also bidder->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } @@ -176,7 +181,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) if(owner || sObjectMgr.GetPlayerAccountIdByGUID(owner_guid)) { std::ostringstream msgAuctionSalePendingSubject; - msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING; + msgAuctionSalePendingSubject << auction->itemTemplate << ":0:" << AUCTION_SALE_PENDING; std::ostringstream msgAuctionSalePendingBody; uint32 auctionCut = auction->GetAuctionCut(); @@ -196,7 +201,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) } } -//call this method to send mail to auction owner, when auction is successful, it does not clear ram +// call this method to send mail to auction owner, when auction is successful, it does not clear ram void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) { ObjectGuid owner_guid = ObjectGuid(HIGHGUID_PLAYER, auction->owner); @@ -210,7 +215,7 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) if(owner || owner_accId) { std::ostringstream msgAuctionSuccessfulSubject; - msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL; + msgAuctionSuccessfulSubject << auction->itemTemplate << ":0:" << AUCTION_SUCCESSFUL; std::ostringstream auctionSuccessfulBody; uint32 auctionCut = auction->GetAuctionCut(); @@ -226,26 +231,24 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) if (owner) { - //FIXME: what do if owner offline + // FIXME: what do if owner offline owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); - //send auction owner notification, bidder must be current! - owner->GetSession()->SendAuctionOwnerNotification( auction ); } MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str()) .SetMoney(profit) - .SendMailTo(MailReceiver(owner, owner_guid), auction, MAIL_CHECK_MASK_COPIED, HOUR); + .SendMailTo(MailReceiver(owner, owner_guid), auction, MAIL_CHECK_MASK_COPIED); } } -//does not clear ram +// does not clear ram void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction ) -{ //return an item in auction to its owner by mail - Item *pItem = GetAItem(auction->item_guidlow); +{ // return an item in auction to its owner by mail + Item *pItem = GetAItem(auction->itemGuidLow); if(!pItem) { - sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow); + sLog.outError("Auction item (GUID: %u) not found, and lost.", auction->itemGuidLow); return; } @@ -260,7 +263,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction ) if(owner || owner_accId) { std::ostringstream subject; - subject << auction->item_template << ":0:" << AUCTION_EXPIRED << ":0:0"; + subject << auction->itemGuidLow << ":0:" << AUCTION_EXPIRED << ":0:0"; if ( owner ) owner->GetSession()->SendAuctionOwnerNotification( auction ); @@ -359,7 +362,7 @@ void AuctionHouseMgr::LoadAuctions() return; } - result = CharacterDatabase.Query( "SELECT id,houseid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auction" ); + result = CharacterDatabase.Query( "SELECT id,houseid,itemguid,item_template,itemowner,buyoutprice,time,moneyTime,buyguid,lastbid,startbid,deposit FROM auction" ); if( !result ) { barGoLink bar(1); @@ -382,24 +385,25 @@ void AuctionHouseMgr::LoadAuctions() auction = new AuctionEntry; auction->Id = fields[0].GetUInt32(); uint32 houseid = fields[1].GetUInt32(); - auction->item_guidlow = fields[2].GetUInt32(); - auction->item_template = fields[3].GetUInt32(); + auction->itemGuidLow = fields[2].GetUInt32(); + auction->itemTemplate = fields[3].GetUInt32(); auction->owner = fields[4].GetUInt32(); auction->buyout = fields[5].GetUInt32(); - auction->expire_time = fields[6].GetUInt32(); - auction->bidder = fields[7].GetUInt32(); - auction->bid = fields[8].GetUInt32(); - auction->startbid = fields[9].GetUInt32(); - auction->deposit = fields[10].GetUInt32(); + auction->expireTime = fields[6].GetUInt32(); + auction->moneyDeliveryTime = fields[7].GetUInt32(); + auction->bidder = fields[8].GetUInt32(); + auction->bid = fields[9].GetUInt32(); + auction->startbid = fields[10].GetUInt32(); + auction->deposit = fields[11].GetUInt32(); auction->auctionHouseEntry = NULL; // init later // check if sold item exists for guid // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems) - Item* pItem = GetAItem(auction->item_guidlow); + Item* pItem = GetAItem(auction->itemGuidLow); if (!pItem) { auction->DeleteFromDB(); - sLog.outError("Auction %u has not a existing item : %u, deleted", auction->Id, auction->item_guidlow); + sLog.outError("Auction %u has not a existing item : %u, deleted", auction->Id, auction->itemGuidLow); delete auction; continue; } @@ -413,14 +417,14 @@ void AuctionHouseMgr::LoadAuctions() // Attempt send item back to owner std::ostringstream msgAuctionCanceledOwner; - msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0"; + msgAuctionCanceledOwner << auction->itemTemplate << ":0:" << AUCTION_CANCELED << ":0:0"; // item will deleted or added to received mail list MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body .AddItem(pItem) .SendMailTo(MailReceiver(ObjectGuid(HIGHGUID_PLAYER, auction->owner)), auction, MAIL_CHECK_MASK_COPIED); - RemoveAItem(auction->item_guidlow); + RemoveAItem(auction->itemGuidLow); auction->DeleteFromDB(); delete auction; @@ -543,32 +547,46 @@ void AuctionHouseObject::Update() time_t curTime = sWorld.GetGameTime(); ///- Handle expired auctions AuctionEntryMap::iterator next; - for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end();itr = next) + for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); itr = next) { next = itr; ++next; - if (curTime > (itr->second->expire_time)) - { - ///- Either cancel the auction if there was no bidder - if (itr->second->bidder == 0) - { - sAuctionMgr.SendAuctionExpiredMail( itr->second ); - } - ///- Or perform the transaction - else - { - //we should send an "item sold" message if the seller is online - //we send the item to the winner - //we send the money to the seller - sAuctionMgr.SendAuctionSuccessfulMail( itr->second ); - sAuctionMgr.SendAuctionWonMail( itr->second ); - } - ///- In any case clear the auction - itr->second->DeleteFromDB(); - sAuctionMgr.RemoveAItem(itr->second->item_guidlow); - delete itr->second; - RemoveAuction(itr->first); + if (itr->second->moneyDeliveryTime) + { + if (curTime > itr->second->moneyDeliveryTime) + { + sAuctionMgr.SendAuctionSuccessfulMail( itr->second ); + + itr->second->DeleteFromDB(); + sAuctionMgr.RemoveAItem(itr->second->itemGuidLow); + delete itr->second; + RemoveAuction(itr->first); + } + } + else + { + if (curTime > itr->second->expireTime) + { + ///- Either cancel the auction if there was no bidder + if (itr->second->bidder == 0) + { + sAuctionMgr.SendAuctionExpiredMail( itr->second ); + } + ///- Or perform the transaction + else + { + itr->second->moneyDeliveryTime = time(NULL) + HOUR; + sAuctionMgr.SendAuctionWonMail( itr->second ); + continue; + } + + ///- In any case clear the auction + itr->second->DeleteFromDB(); + sAuctionMgr.RemoveAItem(itr->second->itemGuidLow); + delete itr->second; + RemoveAuction(itr->first); + } } } } @@ -578,6 +596,8 @@ void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) { AuctionEntry *Aentry = itr->second; + if(Aentry->moneyDeliveryTime) + continue; if( Aentry && Aentry->bidder == player->GetGUIDLow() ) { if (itr->second->BuildAuctionInfo(data)) @@ -592,6 +612,8 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) { AuctionEntry *Aentry = itr->second; + if(Aentry->moneyDeliveryTime) + continue; if( Aentry && Aentry->owner == player->GetGUIDLow() ) { if(Aentry->BuildAuctionInfo(data)) @@ -611,7 +633,9 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) { AuctionEntry *Aentry = itr->second; - Item *item = sAuctionMgr.GetAItem(Aentry->item_guidlow); + if(Aentry->moneyDeliveryTime) + continue; + Item *item = sAuctionMgr.GetAItem(Aentry->itemGuidLow); if (!item) continue; @@ -662,10 +686,45 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player } } -//this function inserts to WorldPacket auction's data +void AuctionHouseObject::BuildListPendingSales(WorldPacket& data, Player* player, uint32& count) +{ + for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) + { + AuctionEntry *Aentry = itr->second; + if(!Aentry->moneyDeliveryTime) + continue; + if( Aentry && Aentry->owner == player->GetGUIDLow() ) + { + Item *pItem = sAuctionMgr.GetAItem(Aentry->itemGuidLow); + if (!pItem) + { + sLog.outError("Auction: item with guid %u doesn't exist!", Aentry->itemGuidLow); + continue; + } + + std::ostringstream str1; + str1 << Aentry->itemTemplate << ":" << pItem->GetItemRandomPropertyId() << ":" << AUCTION_SUCCESSFUL << ":" << Aentry->Id << ":" << pItem->GetCount(); + + std::ostringstream str2; + str2.width(16); + str2 << std::right << std::hex << Aentry->bidder << std::dec << ":"; + str2 << Aentry->bid << ":" << Aentry->buyout << ":" << Aentry->deposit << ":" << Aentry->GetAuctionCut(); + + data << str1.str(); // string "%d:%d:%d:%d:%d" -> itemId, ItemRandomPropertyId, 2, auctionId, unk1 (stack size?, unused) + data << str2.str(); // string "%16I64X:%d:%d:%d:%d" -> bidderGuid, bid, buyout, deposit, auctionCut + data << uint32(97250); // unk1 + data << uint32(68); // unk2 + float timeLeft = float(Aentry->moneyDeliveryTime - time(NULL)) / float(DAY); + data << float(timeLeft); // time left + ++count; + } + } +} + +// this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const { - Item *pItem = sAuctionMgr.GetAItem(item_guidlow); + Item *pItem = sAuctionMgr.GetAItem(itemGuidLow); if (!pItem) { sLog.outError("auction to item, that doesn't exist !!!!"); @@ -681,19 +740,18 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i))); } - data << uint32(pItem->GetItemRandomPropertyId()); //random item property id - data << uint32(pItem->GetItemSuffixFactor()); //SuffixFactor - data << uint32(pItem->GetCount()); //item->count - data << uint32(pItem->GetSpellCharges()); //item->charge FFFFFFF - data << uint32(0); //Unknown - data << ObjectGuid(HIGHGUID_PLAYER, owner); //Auction->owner - data << uint32(startbid); //Auction->startbid (not sure if useful) - data << uint32(bid ? GetAuctionOutBid() : 0); - //minimal outbid - data << uint32(buyout); //auction->buyout - data << uint32((expire_time-time(NULL))*IN_MILLISECONDS);//time left - data << ObjectGuid(HIGHGUID_PLAYER, bidder); //auction->bidder current - data << uint32(bid); //current bid + data << uint32(pItem->GetItemRandomPropertyId()); // random item property id + data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor + data << uint32(pItem->GetCount()); // item->count + data << uint32(pItem->GetSpellCharges()); // item->charge FFFFFFF + data << uint32(0); // item flags (dynamic?) (0x04 no lockId?) + data << ObjectGuid(HIGHGUID_PLAYER, owner); // Auction->owner + data << uint32(startbid); // Auction->startbid (not sure if useful) + data << uint32(bid ? GetAuctionOutBid() : 0); // minimal outbid + data << uint32(buyout); // auction->buyout + data << uint32((expireTime-time(NULL))*IN_MILLISECONDS);// time left + data << ObjectGuid(HIGHGUID_PLAYER, bidder); // auction->bidder current + data << uint32(bid); // current bid return true; } @@ -720,7 +778,7 @@ void AuctionEntry::DeleteFromDB() const void AuctionEntry::SaveToDB() const { //No SQL injection (no strings) - CharacterDatabase.PExecute("INSERT INTO auction (id,houseid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) " - "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u')", - Id, auctionHouseEntry->houseId, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit); + CharacterDatabase.PExecute("INSERT INTO auction (id,houseid,itemguid,item_template,itemowner,buyoutprice,time,moneyTime,buyguid,lastbid,startbid,deposit) " + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '" UI64FMTD "', '%u', '%u', '%u', '%u')", + Id, auctionHouseEntry->houseId, itemGuidLow, itemTemplate, owner, buyout, (uint64)expireTime, (uint64)moneyDeliveryTime, bidder, bid, startbid, deposit); } diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h index 5ca3deb9c..995ba266f 100644 --- a/src/game/AuctionHouseMgr.h +++ b/src/game/AuctionHouseMgr.h @@ -33,32 +33,37 @@ class WorldPacket; enum AuctionError { - AUCTION_OK = 0, - AUCTION_INTERNAL_ERROR = 2, - AUCTION_NOT_ENOUGHT_MONEY = 3, - AUCTION_ITEM_NOT_FOUND = 4, - CANNOT_BID_YOUR_AUCTION_ERROR = 10 + AUCTION_OK = 0, // depends on enum AuctionAction + AUCTION_ERR_INVENTORY = 1, // depends on enum InventoryChangeResult + AUCTION_ERR_DATABASE = 2, // ERR_AUCTION_DATABASE_ERROR (default) + AUCTION_ERR_NOT_ENOUGH_MONEY = 3, // ERR_NOT_ENOUGH_MONEY + AUCTION_ERR_ITEM_NOT_FOUND = 4, // ERR_ITEM_NOT_FOUND + AUCTION_ERR_HIGHER_BID = 5, // ERR_AUCTION_HIGHER_BID + AUCTION_ERR_BID_INCREMENT = 7, // ERR_AUCTION_BID_INCREMENT + AUCTION_ERR_BID_OWN = 10, // ERR_AUCTION_BID_OWN + AUCTION_ERR_RESTRICTED_ACCOUNT = 13 // ERR_RESTRICTED_ACCOUNT }; enum AuctionAction { - AUCTION_SELL_ITEM = 0, - AUCTION_CANCEL = 1, - AUCTION_PLACE_BID = 2 + AUCTION_STARTED = 0, // ERR_AUCTION_STARTED + AUCTION_REMOVED = 1, // ERR_AUCTION_REMOVED + AUCTION_BID_PLACED = 2 // ERR_AUCTION_BID_PLACED }; struct AuctionEntry { uint32 Id; - uint32 item_guidlow; - uint32 item_template; + uint32 itemGuidLow; + uint32 itemTemplate; uint32 owner; - uint32 startbid; //maybe useless + uint32 startbid; // maybe useless uint32 bid; uint32 buyout; - time_t expire_time; + time_t expireTime; + time_t moneyDeliveryTime; uint32 bidder; - uint32 deposit; //deposit can be calculated only when creating auction + uint32 deposit; // deposit can be calculated only when creating auction AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc // helpers @@ -107,6 +112,7 @@ class AuctionHouseObject void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); + void BuildListPendingSales(WorldPacket& data, Player* player, uint32& count); void BuildListAuctionItems(WorldPacket& data, Player* player, std::wstring const& searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 249992d2d..263c5952c 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -26,6 +26,8 @@ #include "Common.h" #include "SharedDefines.h" #include "ObjectGuid.h" +#include "AuctionHouseMgr.h" +#include "Item.h" struct ItemPrototype; struct AuctionEntry; @@ -347,12 +349,13 @@ class MANGOS_DLL_SPEC WorldSession bool SendItemInfo( uint32 itemid, WorldPacket data ); //auction - void SendAuctionHello(Unit * unit); - void SendAuctionCommandResult( uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0); - void SendAuctionBidderNotification( uint32 location, uint32 auctionId, ObjectGuid bidderGuid, uint32 bidSum, uint32 diff, uint32 item_template); - void SendAuctionOwnerNotification( AuctionEntry * auction ); - void SendAuctionOutbiddedMail( AuctionEntry * auction, uint32 newPrice ); - void SendAuctionCancelledToBidderMail( AuctionEntry* auction ); + void SendAuctionHello(Unit *unit); + void SendAuctionCommandResult(AuctionEntry *auc, AuctionAction Action, AuctionError ErrorCode, InventoryResult invError = EQUIP_ERR_OK); + void SendAuctionBidderNotification(AuctionEntry *auction); + void SendAuctionOwnerNotification(AuctionEntry *auction); + void SendAuctionRemovedNotification(AuctionEntry* auction); + void SendAuctionOutbiddedMail(AuctionEntry *auction); + void SendAuctionCancelledToBidderMail(AuctionEntry *auction); AuctionHouseEntry const* GetCheckedAuctionHouseForAuctioneer(ObjectGuid guid); //Item Enchantment diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d35578b3c..773e3e015 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11390" + #define REVISION_NR "11391" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index cbbc64077..a8d206552 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ - #define REVISION_DB_CHARACTERS "required_11299_02_characters_pet_aura" + #define REVISION_DB_CHARACTERS "required_11391_01_characters_auction" #define REVISION_DB_MANGOS "required_11385_01_mangos_creature_template" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__