Beispiel #1
0
 public void SendTradeStatus(TradeStatusPkt info)
 {
     info.Clear();   // reuse packet
     Player trader = GetPlayer().GetTrader();
     info.PartnerIsSameBnetAccount = trader && trader.GetSession().GetBattlenetAccountId() == GetBattlenetAccountId();
     SendPacket(info);
 }
Beispiel #2
0
        public void SendCancelTrade()
        {
            if (PlayerRecentlyLoggedOut() || PlayerLogout())
                return;

            TradeStatusPkt info = new TradeStatusPkt();
            info.Status = TradeStatus.Cancelled;
            SendTradeStatus(info);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
                }
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
            }
        }