public void SendTradeStatus(TradeStatusPkt info) { info.Clear(); // reuse packet Player trader = GetPlayer().GetTrader(); info.PartnerIsSameBnetAccount = trader && trader.GetSession().GetBattlenetAccountId() == GetBattlenetAccountId(); SendPacket(info); }
public void SendCancelTrade() { if (PlayerRecentlyLoggedOut() || PlayerLogout()) return; TradeStatusPkt info = new TradeStatusPkt(); info.Status = TradeStatus.Cancelled; SendTradeStatus(info); }
void HandleBeginTrade(BeginTrade packet) { TradeData my_trade = GetPlayer().GetTradeData(); if (my_trade == null) return; TradeStatusPkt info = new TradeStatusPkt(); my_trade.GetTrader().GetSession().SendTradeStatus(info); SendTradeStatus(info); }
void HandleSetTradeItem(SetTradeItem setTradeItem) { TradeData my_trade = GetPlayer().GetTradeData(); if (my_trade == null) { return; } TradeStatusPkt info = new TradeStatusPkt(); // invalid slot number if (setTradeItem.TradeSlot >= (byte)TradeSlots.Count) { info.Status = TradeStatus.Cancelled; SendTradeStatus(info); return; } // check cheating, can't fail with correct client operations Item item = GetPlayer().GetItemByPos(setTradeItem.PackSlot, setTradeItem.ItemSlotInPack); if (!item || (setTradeItem.TradeSlot != (byte)TradeSlots.NonTraded && !item.CanBeTraded(false, true))) { info.Status = TradeStatus.Cancelled; SendTradeStatus(info); return; } ObjectGuid iGUID = item.GetGUID(); // prevent place single item into many trade slots using cheating and client bugs if (my_trade.HasItem(iGUID)) { // cheating attempt info.Status = TradeStatus.Cancelled; SendTradeStatus(info); return; } my_trade.UpdateClientStateIndex(); if (setTradeItem.TradeSlot != (byte)TradeSlots.NonTraded && item.IsBindedNotWith(my_trade.GetTrader())) { info.Status = TradeStatus.NotOnTaplist; info.TradeSlot = setTradeItem.TradeSlot; SendTradeStatus(info); return; } my_trade.SetItem((TradeSlots)setTradeItem.TradeSlot, item); }
public void SetAccepted(bool state, bool crosssend = false) { m_accepted = state; if (!state) { TradeStatusPkt info = new TradeStatusPkt(); info.Status = TradeStatus.Unaccepted; if (crosssend) { m_trader.GetSession().SendTradeStatus(info); } else { m_player.GetSession().SendTradeStatus(info); } } }
public void SetMoney(ulong money) { if (m_money == money) { return; } if (!m_player.HasEnoughMoney(money)) { TradeStatusPkt info = new TradeStatusPkt(); info.Status = TradeStatus.Failed; info.BagResult = InventoryResult.NotEnoughMoney; m_player.GetSession().SendTradeStatus(info); return; } m_money = money; SetAccepted(false); GetTraderData().SetAccepted(false); UpdateServerStateIndex(); Update(true); }
void HandleInitiateTrade(InitiateTrade initiateTrade) { if (GetPlayer().GetTradeData() != null) { return; } TradeStatusPkt info = new TradeStatusPkt(); if (!GetPlayer().IsAlive()) { info.Status = TradeStatus.Dead; SendTradeStatus(info); return; } if (GetPlayer().HasUnitState(UnitState.Stunned)) { info.Status = TradeStatus.Stunned; SendTradeStatus(info); return; } if (IsLogingOut()) { info.Status = TradeStatus.LoggingOut; SendTradeStatus(info); return; } if (GetPlayer().IsInFlight()) { info.Status = TradeStatus.TooFarAway; SendTradeStatus(info); return; } if (GetPlayer().GetLevel() < WorldConfig.GetIntValue(WorldCfg.TradeLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.TradeReq), WorldConfig.GetIntValue(WorldCfg.TradeLevelReq)); return; } Player pOther = Global.ObjAccessor.FindPlayer(initiateTrade.Guid); if (!pOther) { info.Status = TradeStatus.NoTarget; SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther.GetTradeData() != null) { info.Status = TradeStatus.PlayerBusy; SendTradeStatus(info); return; } if (!pOther.IsAlive()) { info.Status = TradeStatus.TargetDead; SendTradeStatus(info); return; } if (pOther.IsInFlight()) { info.Status = TradeStatus.TooFarAway; SendTradeStatus(info); return; } if (pOther.HasUnitState(UnitState.Stunned)) { info.Status = TradeStatus.TargetStunned; SendTradeStatus(info); return; } if (pOther.GetSession().IsLogingOut()) { info.Status = TradeStatus.TargetLoggingOut; SendTradeStatus(info); return; } if (pOther.GetSocial().HasIgnore(GetPlayer().GetGUID())) { info.Status = TradeStatus.PlayerIgnored; SendTradeStatus(info); return; } if ((pOther.GetTeam() != GetPlayer().GetTeam() || pOther.HasPlayerFlagEx(PlayerFlagsEx.MercenaryMode) || GetPlayer().HasPlayerFlagEx(PlayerFlagsEx.MercenaryMode)) && (!WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideTrade) && !HasPermission(RBACPermissions.AllowTwoSideTrade))) { info.Status = TradeStatus.WrongFaction; SendTradeStatus(info); return; } if (!pOther.IsWithinDistInMap(GetPlayer(), 11.11f, false)) { info.Status = TradeStatus.TooFarAway; SendTradeStatus(info); return; } if (pOther.GetLevel() < WorldConfig.GetIntValue(WorldCfg.TradeLevelReq)) { SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.TradeOtherReq), WorldConfig.GetIntValue(WorldCfg.TradeLevelReq)); return; } // OK start trade GetPlayer().SetTradeData(new TradeData(GetPlayer(), pOther)); pOther.SetTradeData(new TradeData(pOther, GetPlayer())); info.Status = TradeStatus.Proposed; info.Partner = GetPlayer().GetGUID(); pOther.GetSession().SendTradeStatus(info); }
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); } }