public void AddAuction(AuctionEntry auction) { Cypher.Assert(auction != null); AuctionsMap[auction.Id] = auction; Global.ScriptMgr.OnAuctionAdd(this, auction); }
//this function sends mail to old bidder public void SendAuctionOutbiddedMail(AuctionEntry auction, ulong newPrice, Player newBidder, SQLTransaction trans) { ObjectGuid oldBidder_guid = ObjectGuid.Create(HighGuid.Player, auction.bidder); Player oldBidder = Global.ObjAccessor.FindPlayer(oldBidder_guid); uint oldBidder_accId = 0; if (oldBidder == null) { oldBidder_accId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(oldBidder_guid); } Item item = GetAItem(auction.itemGUIDLow); // old bidder exist if (oldBidder || oldBidder_accId != 0) { if (oldBidder && item) { oldBidder.GetSession().SendAuctionOutBidNotification(auction, item); } new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Outbidded), AuctionEntry.BuildAuctionMailBody(auction.owner, auction.bid, auction.buyout, auction.deposit, auction.GetAuctionCut())) .AddMoney(auction.bid) .SendMailTo(trans, new MailReceiver(oldBidder, auction.bidder), new MailSender(auction), MailCheckMask.Copied); } }
public void LoadAuctions() { uint oldMSTime = Time.GetMSTime(); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_AUCTIONS); SQLResult result = DB.Characters.Query(stmt); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 auctions. DB table `auctionhouse` is empty."); return; } uint count = 0; SQLTransaction trans = new SQLTransaction(); do { AuctionEntry aItem = new AuctionEntry(); if (!aItem.LoadFromDB(result.GetFields())) { aItem.DeleteFromDB(trans); continue; } GetAuctionsMap(aItem.factionTemplateId).AddAuction(aItem); ++count; } while (result.NextRow()); DB.Characters.CommitTransaction(trans); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} auctions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); }
//does not clear ram public void SendAuctionExpiredMail(AuctionEntry auction, SQLTransaction trans) { //return an item in auction to its owner by mail Item item = GetAItem(auction.itemGUIDLow); if (!item) { return; } ObjectGuid owner_guid = ObjectGuid.Create(HighGuid.Player, auction.owner); Player owner = Global.ObjAccessor.FindPlayer(owner_guid); uint owner_accId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(owner_guid); // owner exist if (owner || owner_accId != 0) { if (owner) { owner.GetSession().SendAuctionClosedNotification(auction, 0f, false, item); } new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Expired), AuctionEntry.BuildAuctionMailBody(0, 0, auction.buyout, auction.deposit, 0)) .AddItem(item) .SendMailTo(trans, new MailReceiver(owner, auction.owner), new MailSender(auction), MailCheckMask.Copied, 0); } else { // owner doesn't exist, delete the item Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow, true); } }
//call this method to send mail to auction owner, when auction is successful, it does not clear ram public void SendAuctionSuccessfulMail(AuctionEntry auction, SQLTransaction trans) { ObjectGuid owner_guid = ObjectGuid.Create(HighGuid.Player, auction.owner); Player owner = Global.ObjAccessor.FindPlayer(owner_guid); uint owner_accId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(owner_guid); Item item = GetAItem(auction.itemGUIDLow); // owner exist if (owner || owner_accId != 0) { ulong profit = auction.bid + auction.deposit - auction.GetAuctionCut(); //FIXME: what do if owner offline if (owner && item) { owner.UpdateCriteria(CriteriaTypes.GoldEarnedByAuctions, profit); owner.UpdateCriteria(CriteriaTypes.HighestAuctionSold, auction.bid); // send auction owner notification, bidder must be current! owner.GetSession().SendAuctionClosedNotification(auction, WorldConfig.GetIntValue(WorldCfg.MailDeliveryDelay), true, item); } new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Successful), AuctionEntry.BuildAuctionMailBody(auction.bidder, auction.bid, auction.buyout, auction.deposit, auction.GetAuctionCut())) .AddMoney(profit) .SendMailTo(trans, new MailReceiver(owner, auction.owner), new MailSender(auction), MailCheckMask.Copied, WorldConfig.GetUIntValue(WorldCfg.MailDeliveryDelay)); } }
public void SendAuctionWonNotification(AuctionEntry auction, Item item) { AuctionWonNotification packet = new AuctionWonNotification(); packet.Info.Initialize(auction, item); SendPacket(packet); }
public void SendAuctionOwnerBidNotification(AuctionEntry auction, Item item) { AuctionOwnerBidNotification packet = new AuctionOwnerBidNotification(); packet.Info.Initialize(auction, item); packet.Bidder = ObjectGuid.Create(HighGuid.Player, auction.bidder); packet.MinIncrement = auction.GetAuctionOutBid(); SendPacket(packet); }
public void SendAuctionCommandResult(AuctionEntry auction, AuctionAction action, AuctionError errorCode, uint bidError = 0) { AuctionCommandResult auctionCommandResult = new AuctionCommandResult(); auctionCommandResult.InitializeAuction(auction); auctionCommandResult.Command = action; auctionCommandResult.ErrorCode = errorCode; SendPacket(auctionCommandResult); }
public void SendAuctionOutBidNotification(AuctionEntry auction, Item item) { AuctionOutBidNotification packet = new AuctionOutBidNotification(); packet.BidAmount = auction.bid; packet.MinIncrement = auction.GetAuctionOutBid(); packet.Info.Initialize(auction, item); SendPacket(packet); }
public void SendAuctionClosedNotification(AuctionEntry auction, float mailDelay, bool sold, Item item) { AuctionClosedNotification packet = new AuctionClosedNotification(); packet.Info.Initialize(auction, item); packet.ProceedsMailDelay = mailDelay; packet.Sold = sold; SendPacket(packet); }
public bool RemoveAuction(AuctionEntry auction) { bool wasInMap = AuctionsMap.Remove(auction.Id) ? true : false; Global.ScriptMgr.OnAuctionRemove(this, auction); // we need to delete the entry, it is not referenced any more auction = null; return(wasInMap); }
public void SendAuctionSalePendingMail(AuctionEntry auction, SQLTransaction trans) { ObjectGuid owner_guid = ObjectGuid.Create(HighGuid.Player, auction.owner); Player owner = Global.ObjAccessor.FindPlayer(owner_guid); uint owner_accId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(owner_guid); // owner exist (online or offline) if (owner || owner_accId != 0) { new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.SalePending), AuctionEntry.BuildAuctionMailBody(auction.bidder, auction.bid, auction.buyout, auction.deposit, auction.GetAuctionCut())) .SendMailTo(trans, new MailReceiver(owner, auction.owner), new MailSender(auction), MailCheckMask.Copied); } }
//this function sends mail, when auction is cancelled to old bidder public void SendAuctionCancelledToBidderMail(AuctionEntry auction, SQLTransaction trans) { ObjectGuid bidder_guid = ObjectGuid.Create(HighGuid.Player, auction.bidder); Player bidder = Global.ObjAccessor.FindPlayer(bidder_guid); uint bidder_accId = 0; if (!bidder) { bidder_accId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(bidder_guid); } // bidder exist if (bidder || bidder_accId != 0) { new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.CancelledToBidder), AuctionEntry.BuildAuctionMailBody(auction.owner, auction.bid, auction.buyout, auction.deposit, 0)) .AddMoney(auction.bid) .SendMailTo(trans, new MailReceiver(bidder, auction.bidder), new MailSender(auction), MailCheckMask.Copied); } }
public void SendAuctionWonMail(AuctionEntry auction, SQLTransaction trans) { Item item = GetAItem(auction.itemGUIDLow); if (!item) { return; } uint bidderAccId = 0; ObjectGuid bidderGuid = ObjectGuid.Create(HighGuid.Player, auction.bidder); Player bidder = Global.ObjAccessor.FindPlayer(bidderGuid); // data for gm.log string bidderName = ""; bool logGmTrade = false; if (bidder) { bidderAccId = bidder.GetSession().GetAccountId(); bidderName = bidder.GetName(); logGmTrade = bidder.GetSession().HasPermission(RBACPermissions.LogGmTrade); } else { bidderAccId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(bidderGuid); logGmTrade = Global.AccountMgr.HasPermission(bidderAccId, RBACPermissions.LogGmTrade, Global.WorldMgr.GetRealm().Id.Realm); if (logGmTrade && !Global.CharacterCacheStorage.GetCharacterNameByGuid(bidderGuid, out bidderName)) { bidderName = Global.ObjectMgr.GetCypherString(CypherStrings.Unknown); } } if (logGmTrade) { ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, auction.owner); string ownerName; if (!Global.CharacterCacheStorage.GetCharacterNameByGuid(ownerGuid, out ownerName)) { ownerName = Global.ObjectMgr.GetCypherString(CypherStrings.Unknown); } uint ownerAccId = Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(ownerGuid); Log.outCommand(bidderAccId, $"GM {bidderName} (Account: {bidderAccId}) won item in auction: {item.GetTemplate().GetName()} (Entry: {item.GetEntry()} Count: {item.GetCount()}) and pay money: {auction.bid}. Original owner {ownerName} (Account: {ownerAccId})"); } // receiver exist if (bidder || bidderAccId != 0) { // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ITEM_OWNER); stmt.AddValue(0, auction.bidder); stmt.AddValue(1, item.GetGUID().GetCounter()); trans.Append(stmt); if (bidder) { bidder.GetSession().SendAuctionWonNotification(auction, item); // FIXME: for offline player need also bidder.UpdateCriteria(CriteriaTypes.WonAuctions, 1); } new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Won), AuctionEntry.BuildAuctionMailBody(auction.owner, auction.bid, auction.buyout, 0, 0)) .AddItem(item) .SendMailTo(trans, new MailReceiver(bidder, auction.bidder), new MailSender(auction), MailCheckMask.Copied); } else { // bidder doesn't exist, delete the item Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow, true); } }
public bool RemoveAuction(AuctionEntry auction) { Global.ScriptMgr.OnAuctionRemove(this, auction); return(AuctionsMap.TryRemove(auction.Id, out AuctionEntry removedItem)); }
void HandleAuctionRemoveItem(AuctionRemoveItem packet) { Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None); 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 { ulong auctionCut = auction.GetAuctionCut(); if (!player.HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed { return; } Global.AuctionMgr.SendAuctionCancelledToBidderMail(auction, trans); player.ModifyMoney(-(long)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 HandleAuctionPlaceBid(AuctionPlaceBid packet) { if (packet.AuctionItemID == 0 || packet.BidAmount == 0) { return; // check for cheaters } Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None); 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 && Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(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(-(long)(auction.buyout - auction.bid)); } else { player.ModifyMoney(-(long)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 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, NPCFlags2.None); 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; Item[] items = new Item[packet.Items.Count]; for (var i = 0; i < packet.Items.Count; ++i) { items[i] = GetPlayer().GetItemByGuid(packet.Items[i].Guid); if (!items[i]) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound); return; } if (Global.AuctionMgr.GetAItem(items[i].GetGUID().GetCounter()) || !items[i].CanBeTraded() || items[i].IsNotEmptyBag() || items[i].GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || items[i].m_itemData.Expiration != 0 || items[i].GetCount() < packet.Items[i].UseCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } finalCount += packet.Items[i].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; } if (items[i].GetEntry() != items[j].GetEntry()) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound); return; } } } for (var i = 0; i < packet.Items.Count; ++i) { if (items[i].GetMaxStackCount() < finalCount) { SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError); return; } } Item item = items[0]; uint auctionTime = (uint)(packet.RunTime * WorldConfig.GetFloatValue(WorldCfg.RateAuctionTime)); AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.GetFaction()); ulong 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); for (var i = 0; i < packet.Items.Count; ++i) { Item item2 = items[i]; // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2.GetCount() == packet.Items[i].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() - packet.Items[i].UseCount); item2.SetState(ItemUpdateState.Changed, GetPlayer()); GetPlayer().ItemRemovedQuestCheck(item2.GetEntry(), packet.Items[i].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(-(long)deposit); }