void HandleUnacceptTrade(UnacceptTrade packet) { TradeData my_trade = GetPlayer().GetTradeData(); if (my_trade == null) return; my_trade.SetAccepted(false, true); }
public static void HandleAcceptTradeOpcode(ref PacketReader packet, ref WorldManager manager) { Player player = manager.Character; Player trader = manager.Character.TradeInfo.Trader; TradeData thistrade = manager.Character.TradeInfo; TradeData othertrade = manager.Character.TradeInfo.TraderData; Item[] myitems = new Item[TradeData.TRADE_SLOT_COUNT]; Item[] otheritems = new Item[TradeData.TRADE_SLOT_COUNT]; thistrade.SetAccepted(true); if (thistrade.Money > player.Money) { ChatManager.Instance.SendNotification(player, "You do not have enough gold"); return; } if (othertrade.Money > trader.Money) { ChatManager.Instance.SendNotification(trader, "You do not have enough gold"); return; } for (byte i = 0; i < TradeData.TRADE_SLOT_COUNT; i++) { if (thistrade.GetItem(i)?.IsSoulbound == true) { player.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); return; } if (othertrade.GetItem(i)?.IsSoulbound == true) { player.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); return; } } if (othertrade.Accepted) { //TODO spell cast checks //Inventory checks for (byte i = 0; i < TradeData.TRADE_SLOT_COUNT; i++) { if (othertrade.GetItem(i) != null) { if (!trader.Inventory.CanStoreItem(othertrade.GetItem(i).Entry, othertrade.GetItem(i).StackCount)) { player.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); return; } } if (thistrade.GetItem(i) != null) { if (!player.Inventory.CanStoreItem(thistrade.GetItem(i).Entry, thistrade.GetItem(i).StackCount)) { player.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_CANCELLED); return; } } } //Move items for (byte i = 0; i < TradeData.TRADE_SLOT_COUNT; i++) { player.AddItem(othertrade.GetItem(i)); trader.AddItem(thistrade.GetItem(i)); trader.RemoveItem(othertrade.GetItem(i)); player.RemoveItem(thistrade.GetItem(i)); } //Add money player.Money -= thistrade.Money; player.Money += othertrade.Money; trader.Money -= othertrade.Money; trader.Money += thistrade.Money; //Do spell trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_COMPLETE); player.SendTradeStatus(TradeStatuses.TRADE_STATUS_COMPLETE); player.TradeInfo.Clear(); trader.TradeInfo.Clear(); trader.Dirty = true; player.Dirty = true; } else { trader.SendTradeStatus(TradeStatuses.TRADE_STATUS_ACCEPTED); } }
void HandleAcceptTrade(AcceptTrade acceptTrade) { TradeData my_trade = GetPlayer().GetTradeData(); if (my_trade == null) { return; } Player trader = my_trade.GetTrader(); TradeData his_trade = trader.GetTradeData(); if (his_trade == null) { return; } Item[] myItems = new Item[(int)TradeSlots.Count]; Item[] hisItems = new Item[(int)TradeSlots.Count]; // set before checks for propertly undo at problems (it already set in to client) my_trade.SetAccepted(true); TradeStatusPkt info = new TradeStatusPkt(); if (his_trade.GetServerStateIndex() != acceptTrade.StateIndex) { info.Status = TradeStatus.StateChanged; SendTradeStatus(info); my_trade.SetAccepted(false); return; } if (!GetPlayer().IsWithinDistInMap(trader, 11.11f, false)) { info.Status = TradeStatus.TooFarAway; SendTradeStatus(info); my_trade.SetAccepted(false); return; } // not accept case incorrect money amount if (!GetPlayer().HasEnoughMoney(my_trade.GetMoney())) { info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.NotEnoughMoney; SendTradeStatus(info); my_trade.SetAccepted(false, true); return; } // not accept case incorrect money amount if (!trader.HasEnoughMoney(his_trade.GetMoney())) { info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.NotEnoughMoney; trader.GetSession().SendTradeStatus(info); his_trade.SetAccepted(false, true); return; } if (GetPlayer().GetMoney() >= PlayerConst.MaxMoneyAmount - his_trade.GetMoney()) { info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.TooMuchGold; SendTradeStatus(info); my_trade.SetAccepted(false, true); return; } if (trader.GetMoney() >= PlayerConst.MaxMoneyAmount - my_trade.GetMoney()) { info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.TooMuchGold; trader.GetSession().SendTradeStatus(info); his_trade.SetAccepted(false, true); return; } // not accept if some items now can't be trade (cheating) for (byte i = 0; i < (byte)TradeSlots.Count; ++i) { Item item = my_trade.GetItem((TradeSlots)i); if (item) { if (!item.CanBeTraded(false, true)) { info.Status = TradeStatus.Cancelled; SendTradeStatus(info); return; } if (item.IsBindedNotWith(trader)) { info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.TradeBoundItem; SendTradeStatus(info); return; } } item = his_trade.GetItem((TradeSlots)i); if (item) { if (!item.CanBeTraded(false, true)) { info.Status = TradeStatus.Cancelled; SendTradeStatus(info); return; } } } if (his_trade.IsAccepted()) { SetAcceptTradeMode(my_trade, his_trade, myItems, hisItems); Spell my_spell = null; SpellCastTargets my_targets = new SpellCastTargets(); Spell his_spell = null; SpellCastTargets his_targets = new SpellCastTargets(); // not accept if spell can't be casted now (cheating) uint my_spell_id = my_trade.GetSpell(); if (my_spell_id != 0) { SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(my_spell_id); Item castItem = my_trade.GetSpellCastItem(); if (spellEntry == null || !his_trade.GetItem(TradeSlots.NonTraded) || (my_trade.HasSpellCastItem() && !castItem)) { ClearAcceptTradeMode(my_trade, his_trade); ClearAcceptTradeMode(myItems, hisItems); my_trade.SetSpell(0); return; } my_spell = new Spell(GetPlayer(), spellEntry, TriggerCastFlags.FullMask); my_spell.m_CastItem = castItem; my_targets.SetTradeItemTarget(GetPlayer()); my_spell.m_targets = my_targets; SpellCastResult res = my_spell.CheckCast(true); if (res != SpellCastResult.SpellCastOk) { my_spell.SendCastResult(res); ClearAcceptTradeMode(my_trade, his_trade); ClearAcceptTradeMode(myItems, hisItems); my_spell.Dispose(); my_trade.SetSpell(0); return; } } // not accept if spell can't be casted now (cheating) uint his_spell_id = his_trade.GetSpell(); if (his_spell_id != 0) { SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(his_spell_id); Item castItem = his_trade.GetSpellCastItem(); if (spellEntry == null || !my_trade.GetItem(TradeSlots.NonTraded) || (his_trade.HasSpellCastItem() && !castItem)) { his_trade.SetSpell(0); ClearAcceptTradeMode(my_trade, his_trade); ClearAcceptTradeMode(myItems, hisItems); return; } his_spell = new Spell(trader, spellEntry, TriggerCastFlags.FullMask); his_spell.m_CastItem = castItem; his_targets.SetTradeItemTarget(trader); his_spell.m_targets = his_targets; SpellCastResult res = his_spell.CheckCast(true); if (res != SpellCastResult.SpellCastOk) { his_spell.SendCastResult(res); ClearAcceptTradeMode(my_trade, his_trade); ClearAcceptTradeMode(myItems, hisItems); my_spell.Dispose(); his_spell.Dispose(); his_trade.SetSpell(0); return; } } // inform partner client info.Status = TradeStatus.Accepted; trader.GetSession().SendTradeStatus(info); // test if item will fit in each inventory TradeStatusPkt myCanCompleteInfo = new TradeStatusPkt(); TradeStatusPkt hisCanCompleteInfo = new TradeStatusPkt(); hisCanCompleteInfo.BagResult = trader.CanStoreItems(myItems, (int)TradeSlots.TradedCount, ref hisCanCompleteInfo.ItemID); myCanCompleteInfo.BagResult = GetPlayer().CanStoreItems(hisItems, (int)TradeSlots.TradedCount, ref myCanCompleteInfo.ItemID); ClearAcceptTradeMode(myItems, hisItems); // in case of missing space report error if (myCanCompleteInfo.BagResult != InventoryResult.Ok) { ClearAcceptTradeMode(my_trade, his_trade); myCanCompleteInfo.Status = TradeStatus.Failed; trader.GetSession().SendTradeStatus(myCanCompleteInfo); myCanCompleteInfo.FailureForYou = true; SendTradeStatus(myCanCompleteInfo); my_trade.SetAccepted(false); his_trade.SetAccepted(false); return; } else if (hisCanCompleteInfo.BagResult != InventoryResult.Ok) { ClearAcceptTradeMode(my_trade, his_trade); hisCanCompleteInfo.Status = TradeStatus.Failed; SendTradeStatus(hisCanCompleteInfo); hisCanCompleteInfo.FailureForYou = true; trader.GetSession().SendTradeStatus(hisCanCompleteInfo); my_trade.SetAccepted(false); his_trade.SetAccepted(false); return; } // execute trade: 1. remove for (byte i = 0; i < (int)TradeSlots.TradedCount; ++i) { if (myItems[i]) { myItems[i].SetGiftCreator(GetPlayer().GetGUID()); GetPlayer().MoveItemFromInventory(myItems[i].GetBagSlot(), myItems[i].GetSlot(), true); } if (hisItems[i]) { hisItems[i].SetGiftCreator(trader.GetGUID()); trader.MoveItemFromInventory(hisItems[i].GetBagSlot(), hisItems[i].GetSlot(), true); } } // execute trade: 2. store MoveItems(myItems, hisItems); // logging money if (HasPermission(RBACPermissions.LogGmTrade)) { if (my_trade.GetMoney() > 0) { Log.outCommand(GetPlayer().GetSession().GetAccountId(), "GM {0} (Account: {1}) give money (Amount: {2}) to player: {3} (Account: {4})", GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), my_trade.GetMoney(), trader.GetName(), trader.GetSession().GetAccountId()); } if (his_trade.GetMoney() > 0) { Log.outCommand(GetPlayer().GetSession().GetAccountId(), "GM {0} (Account: {1}) give money (Amount: {2}) to player: {3} (Account: {4})", trader.GetName(), trader.GetSession().GetAccountId(), his_trade.GetMoney(), GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId()); } } // update money GetPlayer().ModifyMoney(-(long)my_trade.GetMoney()); GetPlayer().ModifyMoney((long)his_trade.GetMoney()); trader.ModifyMoney(-(long)his_trade.GetMoney()); trader.ModifyMoney((long)my_trade.GetMoney()); if (my_spell) { my_spell.Prepare(my_targets); } if (his_spell) { his_spell.Prepare(his_targets); } // cleanup ClearAcceptTradeMode(my_trade, his_trade); GetPlayer().SetTradeData(null); trader.SetTradeData(null); // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) SQLTransaction trans = new SQLTransaction(); GetPlayer().SaveInventoryAndGoldToDB(trans); trader.SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); info.Status = TradeStatus.Complete; trader.GetSession().SendTradeStatus(info); SendTradeStatus(info); } else { info.Status = TradeStatus.Accepted; trader.GetSession().SendTradeStatus(info); } }