void HandleAuctionPlaceBid(AuctionPlaceBid packet) { if (packet.AuctionItemID == 0 || packet.BidAmount == 0) { return; // check for cheaters } Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionPlaceBid - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); AuctionEntry auction = auctionHouse.GetAuction(packet.AuctionItemID); Player player = GetPlayer(); if (auction == null || auction.owner == player.GetGUID().GetCounter()) { //you cannot bid your own auction: SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn); return; } // impossible have online own another character (use this for speedup check in case online owner) ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, auction.owner); Player auction_owner = Global.ObjAccessor.FindPlayer(ownerGuid); if (!auction_owner && ObjectManager.GetPlayerAccountIdByGUID(ownerGuid) == player.GetSession().GetAccountId()) { //you cannot bid your another character auction: SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn); return; } // cheating if (packet.BidAmount <= auction.bid || packet.BidAmount < auction.startbid) { return; } // price too low for next bid if not buyout if ((packet.BidAmount < auction.buyout || auction.buyout == 0) && packet.BidAmount < auction.bid + auction.GetAuctionOutBid()) { // client already test it but just in case ... SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.HigherBid); return; } if (!player.HasEnoughMoney(packet.BidAmount)) { // client already test it but just in case ... SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.NotEnoughtMoney); return; } SQLTransaction trans = new SQLTransaction(); if (packet.BidAmount < auction.buyout || auction.buyout == 0) { if (auction.bidder > 0) { if (auction.bidder == player.GetGUID().GetCounter()) { player.ModifyMoney(-(long)(packet.BidAmount - auction.bid)); } else { // mail to last bidder and return money Global.AuctionMgr.SendAuctionOutbiddedMail(auction, packet.BidAmount, GetPlayer(), trans); player.ModifyMoney(-(long)packet.BidAmount); } } else { player.ModifyMoney(-(long)packet.BidAmount); } auction.bidder = player.GetGUID().GetCounter(); auction.bid = (uint)packet.BidAmount; GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, packet.BidAmount); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_AUCTION_BID); stmt.AddValue(0, auction.bidder); stmt.AddValue(1, auction.bid); stmt.AddValue(2, auction.Id); trans.Append(stmt); SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok); // Not sure if we must send this now. Player owner = Global.ObjAccessor.FindConnectedPlayer(ObjectGuid.Create(HighGuid.Player, auction.owner)); Item item = Global.AuctionMgr.GetAItem(auction.itemGUIDLow); if (owner && item) { owner.GetSession().SendAuctionOwnerBidNotification(auction, item); } } else { //buyout: if (player.GetGUID().GetCounter() == auction.bidder) { player.ModifyMoney(-auction.buyout - auction.bid); } else { player.ModifyMoney(-auction.buyout); if (auction.bidder != 0) //buyout for bidded auction .. { Global.AuctionMgr.SendAuctionOutbiddedMail(auction, auction.buyout, GetPlayer(), trans); } } auction.bidder = player.GetGUID().GetCounter(); auction.bid = auction.buyout; GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, auction.buyout); SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok); //- Mails must be under transaction control too to prevent data loss Global.AuctionMgr.SendAuctionSalePendingMail(auction, trans); Global.AuctionMgr.SendAuctionSuccessfulMail(auction, trans); Global.AuctionMgr.SendAuctionWonMail(auction, trans); auction.DeleteFromDB(trans); Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow); auctionHouse.RemoveAuction(auction); } player.SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); }
void HandleAuctionRemoveItem(AuctionRemoveItem packet) { Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionRemoveItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); AuctionEntry auction = auctionHouse.GetAuction((uint)packet.AuctionItemID); Player player = GetPlayer(); SQLTransaction trans = new SQLTransaction(); if (auction != null && auction.owner == player.GetGUID().GetCounter()) { Item pItem = Global.AuctionMgr.GetAItem(auction.itemGUIDLow); if (pItem) { if (auction.bidder > 0) // If we have a bidder, we have to send him the money he paid { uint auctionCut = auction.GetAuctionCut(); if (!player.HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed { return; } Global.AuctionMgr.SendAuctionCancelledToBidderMail(auction, trans); player.ModifyMoney(-auctionCut); } // item will deleted or added to received mail list new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Canceled), AuctionEntry.BuildAuctionMailBody(0, 0, auction.buyout, auction.deposit, 0)) .AddItem(pItem) .SendMailTo(trans, new MailReceiver(player), new MailSender(auction), MailCheckMask.Copied); } else { Log.outError(LogFilter.Network, "Auction id: {0} got non existing item (item guid : {1})!", auction.Id, auction.itemGUIDLow); SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError); return; } } else { SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError); //this code isn't possible ... maybe there should be assert Log.outError(LogFilter.Network, "CHEATER: {0} tried to cancel auction (id: {1}) of another player or auction is null", player.GetGUID().ToString(), packet.AuctionItemID); return; } //inform player, that auction is removed SendAuctionCommandResult(auction, AuctionAction.Cancel, AuctionError.Ok); // Now remove the auction player.SaveInventoryAndGoldToDB(trans); auction.DeleteFromDB(trans); DB.Characters.CommitTransaction(trans); Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow); auctionHouse.RemoveAuction(auction); }
void HandleAuctionSellItem(AuctionSellItem packet) { foreach (var aitem in packet.Items) { if (aitem.Guid.IsEmpty() || aitem.UseCount == 0 || aitem.UseCount > 1000) { return; } } if (packet.MinBid == 0 || packet.RunTime == 0) { return; } if (packet.MinBid > PlayerConst.MaxMoneyAmount || packet.BuyoutPrice > PlayerConst.MaxMoneyAmount) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - Player {0} ({1}) attempted to sell item with higher price than max gold amount.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer); if (!creature) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString()); return; } uint houseId = 0; AuctionHouseRecord auctionHouseEntry = Global.AuctionMgr.GetAuctionHouseEntry(creature.getFaction(), ref houseId); if (auctionHouseEntry == null) { Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} has wrong faction.", packet.Auctioneer.ToString()); return; } packet.RunTime *= Time.Minute; switch (packet.RunTime) { case 1 * SharedConst.MinAuctionTime: case 2 * SharedConst.MinAuctionTime: case 4 * SharedConst.MinAuctionTime: break; default: return; } if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } uint finalCount = 0; foreach (var packetItem in packet.Items) { Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid); if (!aitem) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound); return; } if (Global.AuctionMgr.GetAItem(aitem.GetGUID().GetCounter()) || !aitem.CanBeTraded() || aitem.IsNotEmptyBag() || aitem.GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || aitem.GetUInt32Value(ItemFields.Duration) != 0 || aitem.GetCount() < packetItem.UseCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } finalCount += packetItem.UseCount; } if (packet.Items.Empty()) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } if (finalCount == 0) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } // check if there are 2 identical guids, in this case user is most likely cheating for (int i = 0; i < packet.Items.Count; ++i) { for (int j = i + 1; j < packet.Items.Count; ++j) { if (packet.Items[i].Guid == packet.Items[j].Guid) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } } } foreach (var packetItem in packet.Items) { Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid); if (aitem.GetMaxStackCount() < finalCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } } Item item = GetPlayer().GetItemByGuid(packet.Items[0].Guid); uint auctionTime = (uint)(packet.RunTime * WorldConfig.GetFloatValue(WorldCfg.RateAuctionTime)); AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction()); uint deposit = Global.AuctionMgr.GetAuctionDeposit(auctionHouseEntry, packet.RunTime, item, finalCount); if (!GetPlayer().HasEnoughMoney(deposit)) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.NotEnoughtMoney); return; } AuctionEntry AH = new AuctionEntry(); SQLTransaction trans; if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionAuction)) { AH.auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD } else { AH.auctioneer = creature.GetSpawnId(); } // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (packet.Items.Count == 1 && item.GetCount() == packet.Items[0].UseCount) { if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})", GetPlayerName(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount()); } AH.Id = Global.ObjectMgr.GenerateAuctionID(); AH.itemGUIDLow = item.GetGUID().GetCounter(); AH.itemEntry = item.GetEntry(); AH.itemCount = item.GetCount(); AH.owner = GetPlayer().GetGUID().GetCounter(); AH.startbid = (uint)packet.MinBid; AH.bidder = 0; AH.bid = 0; AH.buyout = (uint)packet.BuyoutPrice; AH.expire_time = Time.UnixTime + auctionTime; AH.deposit = deposit; AH.etime = packet.RunTime; AH.auctionHouseEntry = auctionHouseEntry; Log.outInfo(LogFilter.Network, "CMSG_AUCTION_SELL_ITEM: {0} {1} is selling item {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}", GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), item.GetGUID().ToString(), item.GetTemplate().GetName(), AH.auctioneer, item.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId()); Global.AuctionMgr.AddAItem(item); auctionHouse.AddAuction(AH); GetPlayer().MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true); trans = new SQLTransaction(); item.DeleteFromInventoryDB(trans); item.SaveToDB(trans); AH.SaveToDB(trans); GetPlayer().SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok); GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1); } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size { Item newItem = item.CloneItem(finalCount, GetPlayer()); if (!newItem) { Log.outError(LogFilter.Network, "CMSG_AuctionAction.SellItem: Could not create clone of item {0}", item.GetEntry()); SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } if (HasPermission(RBACPermissions.LogGmTrade)) { Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})", GetPlayerName(), GetAccountId(), newItem.GetTemplate().GetName(), newItem.GetEntry(), newItem.GetCount()); } AH.Id = Global.ObjectMgr.GenerateAuctionID(); AH.itemGUIDLow = newItem.GetGUID().GetCounter(); AH.itemEntry = newItem.GetEntry(); AH.itemCount = newItem.GetCount(); AH.owner = GetPlayer().GetGUID().GetCounter(); AH.startbid = (uint)packet.MinBid; AH.bidder = 0; AH.bid = 0; AH.buyout = (uint)packet.BuyoutPrice; AH.expire_time = Time.UnixTime + auctionTime; AH.deposit = deposit; AH.etime = packet.RunTime; AH.auctionHouseEntry = auctionHouseEntry; Log.outInfo(LogFilter.Network, "CMSG_AuctionAction.SellItem: {0} {1} is selling {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}", GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), newItem.GetGUID().ToString(), newItem.GetTemplate().GetName(), AH.auctioneer, newItem.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId()); Global.AuctionMgr.AddAItem(newItem); auctionHouse.AddAuction(AH); foreach (var packetItem in packet.Items) { Item item2 = GetPlayer().GetItemByGuid(packetItem.Guid); // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2.GetCount() == packetItem.UseCount) { GetPlayer().MoveItemFromInventory(item2.GetBagSlot(), item2.GetSlot(), true); trans = new SQLTransaction(); item2.DeleteFromInventoryDB(trans); item2.DeleteFromDB(trans); DB.Characters.CommitTransaction(trans); } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { item2.SetCount(item2.GetCount() - packetItem.UseCount); item2.SetState(ItemUpdateState.Changed, GetPlayer()); GetPlayer().ItemRemovedQuestCheck(item2.GetEntry(), packetItem.UseCount); item2.SendUpdateToPlayer(GetPlayer()); trans = new SQLTransaction(); item2.SaveToDB(trans); DB.Characters.CommitTransaction(trans); } } trans = new SQLTransaction(); newItem.SaveToDB(trans); AH.SaveToDB(trans); GetPlayer().SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok); GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1); } GetPlayer().ModifyMoney(-deposit); }