void HandleTransmogrifyItems(TransmogrifyItems transmogrifyItems)
        {
            Player player = GetPlayer();

            // Validate
            if (!player.GetNPCIfCanInteractWith(transmogrifyItems.Npc, NPCFlags.Transmogrifier, NPCFlags2.None))
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Unit (GUID: {0}) not found or player can't interact with it.", transmogrifyItems.ToString());
                return;
            }

            long cost = 0;
            Dictionary <Item, uint> transmogItems = new Dictionary <Item, uint>();
            Dictionary <Item, uint> illusionItems = new Dictionary <Item, uint>();

            List <Item> resetAppearanceItems = new List <Item>();
            List <Item> resetIllusionItems   = new List <Item>();
            List <uint> bindAppearances      = new List <uint>();

            foreach (TransmogrifyItem transmogItem in transmogrifyItems.Items)
            {
                // slot of the transmogrified item
                if (transmogItem.Slot >= EquipmentSlot.End)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Player ({0}, name: {1}) tried to transmogrify wrong slot {2} when transmogrifying items.", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot);
                    return;
                }

                // transmogrified item
                Item itemTransmogrified = player.GetItemByPos(InventorySlots.Bag0, (byte)transmogItem.Slot);
                if (!itemTransmogrified)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - Player (GUID: {0}, name: {1}) tried to transmogrify an invalid item in a valid slot (slot: {2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot);
                    return;
                }

                if (transmogItem.ItemModifiedAppearanceID != 0)
                {
                    ItemModifiedAppearanceRecord itemModifiedAppearance = CliDB.ItemModifiedAppearanceStorage.LookupByKey(transmogItem.ItemModifiedAppearanceID);
                    if (itemModifiedAppearance == null)
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using invalid appearance ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID);
                        return;
                    }

                    var pairValue = GetCollectionMgr().HasItemAppearance((uint)transmogItem.ItemModifiedAppearanceID);
                    if (!pairValue.Item1)
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using appearance he has not collected ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID);
                        return;
                    }
                    ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemModifiedAppearance.ItemID);
                    if (player.CanUseItem(itemTemplate) != InventoryResult.Ok)
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify using appearance he can never use ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.ItemModifiedAppearanceID);
                        return;
                    }

                    // validity of the transmogrification items
                    if (!Item.CanTransmogrifyItemWithItem(itemTransmogrified, itemModifiedAppearance))
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} failed CanTransmogrifyItemWithItem ({2} with appearance {3}).", player.GetGUID().ToString(), player.GetName(), itemTransmogrified.GetEntry(), transmogItem.ItemModifiedAppearanceID);
                        return;
                    }

                    transmogItems[itemTransmogrified] = (uint)transmogItem.ItemModifiedAppearanceID;
                    if (pairValue.Item2)
                    {
                        bindAppearances.Add((uint)transmogItem.ItemModifiedAppearanceID);
                    }

                    // add cost
                    cost += itemTransmogrified.GetSellPrice(_player);
                }
                else
                {
                    resetAppearanceItems.Add(itemTransmogrified);
                }

                if (transmogItem.SpellItemEnchantmentID != 0)
                {
                    if (transmogItem.Slot != EquipmentSlot.MainHand && transmogItem.Slot != EquipmentSlot.OffHand)
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion into non-weapon slot ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.Slot);
                        return;
                    }

                    SpellItemEnchantmentRecord illusion = CliDB.SpellItemEnchantmentStorage.LookupByKey(transmogItem.SpellItemEnchantmentID);
                    if (illusion == null)
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using invalid enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID);
                        return;
                    }

                    if (illusion.ItemVisual == 0 || !illusion.Flags.HasAnyFlag(EnchantmentSlotMask.Collectable))
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not allowed enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID);
                        return;
                    }

                    PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(illusion.TransmogPlayerConditionID);
                    if (condition != null)
                    {
                        if (!ConditionManager.IsPlayerMeetingCondition(player, condition))
                        {
                            Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not collected enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID);
                            return;
                        }
                    }

                    if (illusion.ScalingClassRestricted > 0 && illusion.ScalingClassRestricted != (byte)player.GetClass())
                    {
                        Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not allowed class enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID);
                        return;
                    }

                    illusionItems[itemTransmogrified] = (uint)transmogItem.SpellItemEnchantmentID;
                    cost += illusion.TransmogCost;
                }
                else
                {
                    resetIllusionItems.Add(itemTransmogrified);
                }
            }

            if (cost != 0) // 0 cost if reverting look
            {
                if (!player.HasEnoughMoney(cost))
                {
                    return;
                }

                player.ModifyMoney(-cost);
            }

            // Everything is fine, proceed
            foreach (var transmogPair in transmogItems)
            {
                Item transmogrified = transmogPair.Key;

                if (!transmogrifyItems.CurrentSpecOnly)
                {
                    transmogrified.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, transmogPair.Value);
                    transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec1, 0);
                    transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec2, 0);
                    transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec3, 0);
                    transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec4, 0);
                }
                else
                {
                    if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec1) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec1, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec2, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec3) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec3, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.TransmogAppearanceSpec4) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.TransmogAppearanceSpec4, transmogrified.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    transmogrified.SetModifier(ItemConst.AppearanceModifierSlotBySpec[player.GetActiveTalentGroup()], transmogPair.Value);
                }

                player.SetVisibleItemSlot(transmogrified.GetSlot(), transmogrified);

                transmogrified.SetNotRefundable(player);
                transmogrified.ClearSoulboundTradeable(player);
                transmogrified.SetState(ItemUpdateState.Changed, player);
            }

            foreach (var illusionPair in illusionItems)
            {
                Item transmogrified = illusionPair.Key;

                if (!transmogrifyItems.CurrentSpecOnly)
                {
                    transmogrified.SetModifier(ItemModifier.EnchantIllusionAllSpecs, illusionPair.Value);
                    transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec1, 0);
                    transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec2, 0);
                    transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec3, 0);
                    transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec4, 0);
                }
                else
                {
                    if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec1) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec1, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec2) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec2, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec3) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec3, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (transmogrified.GetModifier(ItemModifier.EnchantIllusionSpec4) == 0)
                    {
                        transmogrified.SetModifier(ItemModifier.EnchantIllusionSpec4, transmogrified.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    transmogrified.SetModifier(ItemConst.IllusionModifierSlotBySpec[player.GetActiveTalentGroup()], illusionPair.Value);
                }

                player.SetVisibleItemSlot(transmogrified.GetSlot(), transmogrified);

                transmogrified.SetNotRefundable(player);
                transmogrified.ClearSoulboundTradeable(player);
                transmogrified.SetState(ItemUpdateState.Changed, player);
            }

            foreach (Item item in resetAppearanceItems)
            {
                if (!transmogrifyItems.CurrentSpecOnly)
                {
                    item.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, 0);
                    item.SetModifier(ItemModifier.TransmogAppearanceSpec1, 0);
                    item.SetModifier(ItemModifier.TransmogAppearanceSpec2, 0);
                    item.SetModifier(ItemModifier.TransmogAppearanceSpec3, 0);
                    item.SetModifier(ItemModifier.TransmogAppearanceSpec4, 0);
                }
                else
                {
                    if (item.GetModifier(ItemModifier.TransmogAppearanceSpec1) == 0)
                    {
                        item.SetModifier(ItemModifier.TransmogAppearanceSpec1, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0)
                    {
                        item.SetModifier(ItemModifier.TransmogAppearanceSpec2, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.TransmogAppearanceSpec2) == 0)
                    {
                        item.SetModifier(ItemModifier.TransmogAppearanceSpec3, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.TransmogAppearanceSpec4) == 0)
                    {
                        item.SetModifier(ItemModifier.TransmogAppearanceSpec4, item.GetModifier(ItemModifier.TransmogAppearanceAllSpecs));
                    }
                    item.SetModifier(ItemConst.AppearanceModifierSlotBySpec[player.GetActiveTalentGroup()], 0);
                    item.SetModifier(ItemModifier.EnchantIllusionAllSpecs, 0);
                }

                item.SetState(ItemUpdateState.Changed, player);
                player.SetVisibleItemSlot(item.GetSlot(), item);
            }

            foreach (Item item in resetIllusionItems)
            {
                if (!transmogrifyItems.CurrentSpecOnly)
                {
                    item.SetModifier(ItemModifier.EnchantIllusionAllSpecs, 0);
                    item.SetModifier(ItemModifier.EnchantIllusionSpec1, 0);
                    item.SetModifier(ItemModifier.EnchantIllusionSpec2, 0);
                    item.SetModifier(ItemModifier.EnchantIllusionSpec3, 0);
                    item.SetModifier(ItemModifier.EnchantIllusionSpec4, 0);
                }
                else
                {
                    if (item.GetModifier(ItemModifier.EnchantIllusionSpec1) == 0)
                    {
                        item.SetModifier(ItemModifier.EnchantIllusionSpec1, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.EnchantIllusionSpec2) == 0)
                    {
                        item.SetModifier(ItemModifier.EnchantIllusionSpec2, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.EnchantIllusionSpec3) == 0)
                    {
                        item.SetModifier(ItemModifier.EnchantIllusionSpec3, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    if (item.GetModifier(ItemModifier.EnchantIllusionSpec4) == 0)
                    {
                        item.SetModifier(ItemModifier.EnchantIllusionSpec4, item.GetModifier(ItemModifier.EnchantIllusionAllSpecs));
                    }
                    item.SetModifier(ItemConst.IllusionModifierSlotBySpec[player.GetActiveTalentGroup()], 0);
                    item.SetModifier(ItemModifier.TransmogAppearanceAllSpecs, 0);
                }

                item.SetState(ItemUpdateState.Changed, player);
                player.SetVisibleItemSlot(item.GetSlot(), item);
            }

            foreach (uint itemModifedAppearanceId in bindAppearances)
            {
                var itemsProvidingAppearance = GetCollectionMgr().GetItemsProvidingTemporaryAppearance(itemModifedAppearanceId);
                foreach (ObjectGuid itemGuid in itemsProvidingAppearance)
                {
                    Item item = player.GetItemByGuid(itemGuid);
                    if (item)
                    {
                        item.SetNotRefundable(player);
                        item.ClearSoulboundTradeable(player);
                        GetCollectionMgr().AddItemAppearance(item);
                    }
                }
            }
        }
 public virtual void Perform(ItemTemplate item, string currencyCode)
 {
     Perform(item.ID, item.Price.Value, currencyCode);
 }
        public virtual void Perform(ItemTemplate item)
        {
            var currencyCode = CurrencyCode.From(item.Price.Type);

            Perform(item, currencyCode);
        }
示例#4
0
        void HandleUseItem(UseItem packet)
        {
            Player user = GetPlayer();

            // ignore for remote control state
            if (user.m_unitMovedByMe != user)
            {
                return;
            }

            Item item = user.GetUseableItemByPos(packet.PackSlot, packet.Slot);

            if (item == null)
            {
                user.SendEquipError(InventoryResult.ItemNotFound);
                return;
            }

            if (item.GetGUID() != packet.CastItem)
            {
                user.SendEquipError(InventoryResult.ItemNotFound);
                return;
            }

            ItemTemplate proto = item.GetTemplate();

            if (proto == null)
            {
                user.SendEquipError(InventoryResult.ItemNotFound, item);
                return;
            }

            // some item classes can be used only in equipped state
            if (proto.GetInventoryType() != InventoryType.NonEquip && !item.IsEquipped())
            {
                user.SendEquipError(InventoryResult.ItemNotFound, item);
                return;
            }

            InventoryResult msg = user.CanUseItem(item);

            if (msg != InventoryResult.Ok)
            {
                user.SendEquipError(msg, item);
                return;
            }

            // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
            if (proto.GetClass() == ItemClass.Consumable && !proto.GetFlags().HasAnyFlag(ItemFlags.IgnoreDefaultArenaRestrictions) && user.InArena())
            {
                user.SendEquipError(InventoryResult.NotDuringArenaMatch, item);
                return;
            }

            // don't allow items banned in arena
            if (proto.GetFlags().HasAnyFlag(ItemFlags.NotUseableInArena) && user.InArena())
            {
                user.SendEquipError(InventoryResult.NotDuringArenaMatch, item);
                return;
            }

            if (user.IsInCombat())
            {
                for (int i = 0; i < proto.Effects.Count; ++i)
                {
                    SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(proto.Effects[i].SpellID);
                    if (spellInfo != null)
                    {
                        if (!spellInfo.CanBeUsedInCombat())
                        {
                            user.SendEquipError(InventoryResult.NotInCombat, item);
                            return;
                        }
                    }
                }
            }

            // check also  BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
            if (item.GetBonding() == ItemBondingType.OnUse || item.GetBonding() == ItemBondingType.OnAcquire || item.GetBonding() == ItemBondingType.Quest)
            {
                if (!item.IsSoulBound())
                {
                    item.SetState(ItemUpdateState.Changed, user);
                    item.SetBinding(true);
                    GetCollectionMgr().AddItemAppearance(item);
                }
            }

            SpellCastTargets targets = new SpellCastTargets(user, packet.Cast);

            // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
            if (!Global.ScriptMgr.OnItemUse(user, item, targets, packet.Cast.CastID))
            {
                // no script or script not process request by self
                user.CastItemUseSpell(item, targets, packet.Cast.CastID, packet.Cast.Misc);
            }
        }
示例#5
0
        public void SendListInventory(ObjectGuid vendorGuid)
        {
            Creature vendor = GetPlayer().GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor, NPCFlags2.None);

            if (vendor == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: SendListInventory - {0} not found or you can not interact with him.", vendorGuid.ToString());
                GetPlayer().SendSellError(SellResult.CantFindVendor, null, ObjectGuid.Empty);
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            // Stop the npc if moving
            if (vendor.HasUnitState(UnitState.Moving))
            {
                vendor.StopMoving();
            }

            VendorItemData vendorItems  = vendor.GetVendorItems();
            int            rawItemCount = vendorItems != null?vendorItems.GetItemCount() : 0;

            VendorInventory packet = new VendorInventory();

            packet.Vendor = vendor.GetGUID();

            float discountMod = GetPlayer().GetReputationPriceDiscount(vendor);
            byte  count       = 0;

            for (uint slot = 0; slot < rawItemCount; ++slot)
            {
                VendorItem vendorItem = vendorItems.GetItem(slot);
                if (vendorItem == null)
                {
                    continue;
                }

                VendorItemPkt item = new VendorItemPkt();

                PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vendorItem.PlayerConditionId);
                if (playerCondition != null)
                {
                    if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
                    {
                        item.PlayerConditionFailed = (int)playerCondition.Id;
                    }
                }

                if (vendorItem.Type == ItemVendorType.Item)
                {
                    ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(vendorItem.item);
                    if (itemTemplate == null)
                    {
                        continue;
                    }

                    int leftInStock = vendorItem.maxcount == 0 ? -1 : (int)vendor.GetVendorItemCurrentCount(vendorItem);
                    if (!GetPlayer().IsGameMaster())
                    {
                        if (!Convert.ToBoolean(itemTemplate.GetAllowableClass() & GetPlayer().GetClassMask()) && itemTemplate.GetBonding() == ItemBondingType.OnAcquire)
                        {
                            continue;
                        }

                        if ((itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && GetPlayer().GetTeam() == Team.Alliance) ||
                            (itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && GetPlayer().GetTeam() == Team.Horde))
                        {
                            continue;
                        }

                        if (leftInStock == 0)
                        {
                            continue;
                        }
                    }

                    if (!Global.ConditionMgr.IsObjectMeetingVendorItemConditions(vendor.GetEntry(), vendorItem.item, _player, vendor))
                    {
                        Log.outDebug(LogFilter.Condition, "SendListInventory: conditions not met for creature entry {0} item {1}", vendor.GetEntry(), vendorItem.item);
                        continue;
                    }

                    int price = (int)(vendorItem.IsGoldRequired(itemTemplate) ? Math.Floor(itemTemplate.GetBuyPrice() * discountMod) : 0);

                    int priceMod = GetPlayer().GetTotalAuraModifier(AuraType.ModVendorItemsPrices);
                    if (priceMod != 0)
                    {
                        price -= MathFunctions.CalculatePct(price, priceMod);
                    }

                    item.MuID                = (int)slot + 1;
                    item.Durability          = (int)itemTemplate.MaxDurability;
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Type                = (int)vendorItem.Type;
                    item.Quantity            = leftInStock;
                    item.StackCount          = (int)itemTemplate.GetBuyCount();
                    item.Price               = (ulong)price;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;
                    item.Refundable          = (itemTemplate.GetFlags() & ItemFlags.ItemPurchaseRecord) != 0 && vendorItem.ExtendedCost != 0 && itemTemplate.GetMaxStackSize() == 1;

                    item.Item.ItemID = vendorItem.item;
                    if (!vendorItem.BonusListIDs.Empty())
                    {
                        item.Item.ItemBonus.HasValue           = true;
                        item.Item.ItemBonus.Value.BonusListIDs = vendorItem.BonusListIDs;
                    }

                    packet.Items.Add(item);
                }
                else if (vendorItem.Type == ItemVendorType.Currency)
                {
                    CurrencyTypesRecord currencyTemplate = CliDB.CurrencyTypesStorage.LookupByKey(vendorItem.item);
                    if (currencyTemplate == null)
                    {
                        continue;
                    }

                    if (vendorItem.ExtendedCost == 0)
                    {
                        continue;                             // there's no price defined for currencies, only extendedcost is used
                    }
                    item.MuID                = (int)slot + 1; // client expects counting to start at 1
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Item.ItemID         = vendorItem.item;
                    item.Type                = (int)vendorItem.Type;
                    item.StackCount          = (int)vendorItem.maxcount;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;

                    packet.Items.Add(item);
                }
                else
                {
                    continue;
                }

                if (++count >= SharedConst.MaxVendorItems)
                {
                    break;
                }
            }

            SendPacket(packet);
        }
示例#6
0
        void HandleQuestgiverChooseReward(QuestGiverChooseReward packet)
        {
            Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID);

            if (quest == null)
            {
                return;
            }

            // This is Real Item Entry, not slot id as pre 5.x
            if (packet.ItemChoiceID != 0)
            {
                ItemTemplate rewardProto = Global.ObjectMgr.GetItemTemplate(packet.ItemChoiceID);
                if (rewardProto == null)
                {
                    Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get invalid reward item (Item Entry: {2}) for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID);
                    return;
                }

                bool itemValid = false;
                for (uint i = 0; i < quest.GetRewChoiceItemsCount(); ++i)
                {
                    if (quest.RewardChoiceItemId[i] != 0 && quest.RewardChoiceItemId[i] == packet.ItemChoiceID)
                    {
                        itemValid = true;
                        break;
                    }
                }

                if (!itemValid && quest.PackageID != 0)
                {
                    var questPackageItems = Global.DB2Mgr.GetQuestPackageItems(quest.PackageID);
                    if (questPackageItems != null)
                    {
                        foreach (var questPackageItem in questPackageItems)
                        {
                            if (questPackageItem.ItemID != packet.ItemChoiceID)
                            {
                                continue;
                            }

                            if (_player.CanSelectQuestPackageItem(questPackageItem))
                            {
                                itemValid = true;
                                break;
                            }
                        }
                    }

                    if (!itemValid)
                    {
                        var questPackageItems1 = Global.DB2Mgr.GetQuestPackageItemsFallback(quest.PackageID);
                        if (questPackageItems1 != null)
                        {
                            foreach (var questPackageItem in questPackageItems1)
                            {
                                if (questPackageItem.ItemID != packet.ItemChoiceID)
                                {
                                    continue;
                                }

                                itemValid = true;
                                break;
                            }
                        }
                    }
                }

                if (!itemValid)
                {
                    Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get reward item (Item Entry: {2}) wich is not a reward for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID);
                    return;
                }
            }

            WorldObject obj = GetPlayer();

            if (!quest.HasFlag(QuestFlags.AutoComplete))
            {
                obj = Global.ObjAccessor.GetObjectByTypeMask(GetPlayer(), packet.QuestGiverGUID, TypeMask.Unit | TypeMask.GameObject);
                if (!obj || !obj.HasInvolvedQuest(packet.QuestID))
                {
                    return;
                }

                // some kind of WPE protection
                if (!GetPlayer().CanInteractWithQuestGiver(obj))
                {
                    return;
                }
            }

            if ((!GetPlayer().CanSeeStartQuest(quest) && GetPlayer().GetQuestStatus(packet.QuestID) == QuestStatus.None) ||
                (GetPlayer().GetQuestStatus(packet.QuestID) != QuestStatus.Complete && !quest.IsAutoComplete()))
            {
                Log.outError(LogFilter.Network, "Error in QuestStatus.Complete: player {0} ({1}) tried to complete quest {2}, but is not allowed to do so (possible packet-hacking or high latency)",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.QuestID);
                return;
            }

            if (GetPlayer().CanRewardQuest(quest, packet.ItemChoiceID, true))
            {
                GetPlayer().RewardQuest(quest, packet.ItemChoiceID, obj);

                switch (obj.GetTypeId())
                {
                case TypeId.Unit:
                case TypeId.Player:
                {
                    //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
                    Creature creatureQGiver = obj.ToCreature();
                    // Send next quest
                    Quest nextQuest = _player.GetNextQuest(packet.QuestGiverGUID, quest);
                    if (nextQuest != null)
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player.CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest.IsAutoAccept() && _player.CanAddQuest(nextQuest, true))
                            {
                                _player.AddQuestAndCheckCompletion(nextQuest, obj);
                            }

                            _player.PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
                        }
                    }

                    _player.PlayerTalkClass.ClearMenus();
                    creatureQGiver.GetAI().QuestReward(_player, quest, packet.ItemChoiceID);
                    break;
                }

                case TypeId.GameObject:
                {
                    GameObject questGiver = obj.ToGameObject();
                    // Send next quest
                    Quest nextQuest = _player.GetNextQuest(packet.QuestGiverGUID, quest);
                    if (nextQuest != null)
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player.CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest.IsAutoAccept() && _player.CanAddQuest(nextQuest, true))
                            {
                                _player.AddQuestAndCheckCompletion(nextQuest, obj);
                            }

                            _player.PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
                        }
                    }

                    _player.PlayerTalkClass.ClearMenus();
                    questGiver.GetAI().QuestReward(_player, quest, packet.ItemChoiceID);
                    break;
                }

                default:
                    break;
                }
            }
            else
            {
                GetPlayer().PlayerTalkClass.SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
            }
        }
示例#7
0
        void HandleOpenItem(OpenItem packet)
        {
            Player player = GetPlayer();

            // ignore for remote control state
            if (player.m_unitMovedByMe != player)
            {
                return;
            }

            Item item = player.GetItemByPos(packet.Slot, packet.PackSlot);

            if (!item)
            {
                player.SendEquipError(InventoryResult.ItemNotFound);
                return;
            }

            ItemTemplate proto = item.GetTemplate();

            if (proto == null)
            {
                player.SendEquipError(InventoryResult.ItemNotFound, item);
                return;
            }

            // Verify that the bag is an actual bag or wrapped item that can be used "normally"
            if (!proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot) && !item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))
            {
                player.SendEquipError(InventoryResult.ClientLockedOut, item);
                Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} [guid: {1}] tried to open item [guid: {2}, entry: {3}] which is not openable!",
                             player.GetName(), player.GetGUID().ToString(), item.GetGUID().ToString(), proto.GetId());
                return;
            }

            // locked item
            uint lockId = proto.GetLockID();

            if (lockId != 0)
            {
                LockRecord lockInfo = CliDB.LockStorage.LookupByKey(lockId);
                if (lockInfo == null)
                {
                    player.SendEquipError(InventoryResult.ItemLocked, item);
                    Log.outError(LogFilter.Network, "WORLD:OpenItem: item [guid = {0}] has an unknown lockId: {1}!", item.GetGUID().ToString(), lockId);
                    return;
                }

                // was not unlocked yet
                if (item.IsLocked())
                {
                    player.SendEquipError(InventoryResult.ItemLocked, item);
                    return;
                }
            }

            if (item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))// wrapped?
            {
                PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM);
                stmt.AddValue(0, item.GetGUID().GetCounter());
                SQLResult result = DB.Characters.Query(stmt);

                if (!result.IsEmpty())
                {
                    uint entry = result.Read <uint>(0);
                    uint flags = result.Read <uint>(1);

                    item.SetUInt64Value(ItemFields.GiftCreator, 0);
                    item.SetEntry(entry);
                    item.SetUInt32Value(ItemFields.Flags, flags);
                    item.SetState(ItemUpdateState.Changed, player);
                }
                else
                {
                    Log.outError(LogFilter.Network, "Wrapped item {0} don't have record in character_gifts table and will deleted", item.GetGUID().ToString());
                    player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true);
                    return;
                }

                stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GIFT);
                stmt.AddValue(0, item.GetGUID().GetCounter());
                DB.Characters.Execute(stmt);
            }
            else
            {
                player.SendLoot(item.GetGUID(), LootType.Corpse);
            }
        }
示例#8
0
        void HandleSocketGems(SocketGems socketGems)
        {
            if (socketGems.ItemGuid.IsEmpty())
            {
                return;
            }

            //cheat . tried to socket same gem multiple times
            if ((!socketGems.GemItem[0].IsEmpty() && (socketGems.GemItem[0] == socketGems.GemItem[1] || socketGems.GemItem[0] == socketGems.GemItem[2])) ||
                (!socketGems.GemItem[1].IsEmpty() && (socketGems.GemItem[1] == socketGems.GemItem[2])))
            {
                return;
            }

            Item itemTarget = GetPlayer().GetItemByGuid(socketGems.ItemGuid);

            if (!itemTarget)                                         //missing item to socket
            {
                return;
            }

            ItemTemplate itemProto = itemTarget.GetTemplate();

            if (itemProto == null)
            {
                return;
            }

            //this slot is excepted when applying / removing meta gem bonus
            byte slot = itemTarget.IsEquipped() ? itemTarget.GetSlot() : ItemConst.NullSlot;

            Item[] gems = new Item[ItemConst.MaxGemSockets];
            ItemDynamicFieldGems[] gemData       = new ItemDynamicFieldGems[ItemConst.MaxGemSockets];
            GemPropertiesRecord[]  gemProperties = new GemPropertiesRecord[ItemConst.MaxGemSockets];
            SocketedGem[]          oldGemData    = new SocketedGem[ItemConst.MaxGemSockets];


            for (int i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                Item gem = _player.GetItemByGuid(socketGems.GemItem[i]);
                if (gem)
                {
                    gems[i]            = gem;
                    gemData[i].ItemId  = gem.GetEntry();
                    gemData[i].Context = (byte)gem.m_itemData.Context;
                    for (int b = 0; b < ((List <uint>)gem.m_itemData.BonusListIDs).Count && b < 16; ++b)
                    {
                        gemData[i].BonusListIDs[b] = (ushort)((List <uint>)gem.m_itemData.BonusListIDs)[b];
                    }

                    gemProperties[i] = CliDB.GemPropertiesStorage.LookupByKey(gem.GetTemplate().GetGemProperties());
                }

                oldGemData[i] = itemTarget.GetGem((ushort)i);
            }

            // Find first prismatic socket
            uint firstPrismatic = 0;

            while (firstPrismatic < ItemConst.MaxGemSockets && itemTarget.GetSocketColor(firstPrismatic) != 0)
            {
                ++firstPrismatic;
            }

            for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)                //check for hack maybe
            {
                if (gemProperties[i] == null)
                {
                    continue;
                }

                // tried to put gem in socket where no socket exists (take care about prismatic sockets)
                if (itemTarget.GetSocketColor(i) == 0)
                {
                    // no prismatic socket
                    if (itemTarget.GetEnchantmentId(EnchantmentSlot.Prismatic) == 0)
                    {
                        return;
                    }

                    if (i != firstPrismatic)
                    {
                        return;
                    }
                }

                // Gem must match socket color
                if (ItemConst.SocketColorToGemTypeMask[(int)itemTarget.GetSocketColor(i)] != gemProperties[i].Type)
                {
                    // unless its red, blue, yellow or prismatic
                    if (!ItemConst.SocketColorToGemTypeMask[(int)itemTarget.GetSocketColor(i)].HasAnyFlag(SocketColor.Prismatic) || !gemProperties[i].Type.HasAnyFlag(SocketColor.Prismatic))
                    {
                        return;
                    }
                }
            }

            // check unique-equipped conditions
            for (int i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                if (!gems[i])
                {
                    continue;
                }

                // continue check for case when attempt add 2 similar unique equipped gems in one item.
                ItemTemplate iGemProto = gems[i].GetTemplate();

                // unique item (for new and already placed bit removed enchantments
                if (iGemProto.HasFlag(ItemFlags.UniqueEquippable))
                {
                    for (int j = 0; j < ItemConst.MaxGemSockets; ++j)
                    {
                        if (i == j)                                    // skip self
                        {
                            continue;
                        }

                        if (gems[j])
                        {
                            if (iGemProto.GetId() == gems[j].GetEntry())
                            {
                                GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                                return;
                            }
                        }
                        else if (oldGemData[j] != null)
                        {
                            if (iGemProto.GetId() == oldGemData[j].ItemId)
                            {
                                GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                                return;
                            }
                        }
                    }
                }

                // unique limit type item
                int limit_newcount = 0;
                if (iGemProto.GetItemLimitCategory() != 0)
                {
                    ItemLimitCategoryRecord limitEntry = CliDB.ItemLimitCategoryStorage.LookupByKey(iGemProto.GetItemLimitCategory());
                    if (limitEntry != null)
                    {
                        // NOTE: limitEntry.mode is not checked because if item has limit then it is applied in equip case
                        for (int j = 0; j < ItemConst.MaxGemSockets; ++j)
                        {
                            if (gems[j])
                            {
                                // new gem
                                if (iGemProto.GetItemLimitCategory() == gems[j].GetTemplate().GetItemLimitCategory())
                                {
                                    ++limit_newcount;
                                }
                            }
                            else if (oldGemData[j] != null)
                            {
                                // existing gem
                                ItemTemplate jProto = Global.ObjectMgr.GetItemTemplate(oldGemData[j].ItemId);
                                if (jProto != null)
                                {
                                    if (iGemProto.GetItemLimitCategory() == jProto.GetItemLimitCategory())
                                    {
                                        ++limit_newcount;
                                    }
                                }
                            }
                        }

                        if (limit_newcount > 0 && limit_newcount > _player.GetItemLimitCategoryQuantity(limitEntry))
                        {
                            GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                            return;
                        }
                    }
                }

                // for equipped item check all equipment for duplicate equipped gems
                if (itemTarget.IsEquipped())
                {
                    InventoryResult res = GetPlayer().CanEquipUniqueItem(gems[i], slot, (uint)Math.Max(limit_newcount, 0));
                    if (res != 0)
                    {
                        GetPlayer().SendEquipError(res, itemTarget);
                        return;
                    }
                }
            }

            bool SocketBonusActivated = itemTarget.GemsFitSockets();   //save state of socketbonus

            GetPlayer().ToggleMetaGemsActive(slot, false);             //turn off all metagems (except for the target item)

            //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met

            //remove ALL mods - gem can change item level
            if (itemTarget.IsEquipped())
            {
                _player._ApplyItemMods(itemTarget, itemTarget.GetSlot(), false);
            }

            for (ushort i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                if (gems[i])
                {
                    uint gemScalingLevel = _player.GetLevel();
                    uint fixedLevel      = gems[i].GetModifier(ItemModifier.TimewalkerLevel);
                    if (fixedLevel != 0)
                    {
                        gemScalingLevel = fixedLevel;
                    }

                    itemTarget.SetGem(i, gemData[i], gemScalingLevel);

                    if (gemProperties[i] != null && gemProperties[i].EnchantId != 0)
                    {
                        itemTarget.SetEnchantment(EnchantmentSlot.Sock1 + i, gemProperties[i].EnchantId, 0, 0, GetPlayer().GetGUID());
                    }

                    uint gemCount = 1;
                    GetPlayer().DestroyItemCount(gems[i], ref gemCount, true);
                }
            }

            if (itemTarget.IsEquipped())
            {
                _player._ApplyItemMods(itemTarget, itemTarget.GetSlot(), true);
            }

            Item childItem = _player.GetChildItemByGuid(itemTarget.GetChildItem());

            if (childItem)
            {
                if (childItem.IsEquipped())
                {
                    _player._ApplyItemMods(childItem, childItem.GetSlot(), false);
                }
                childItem.CopyArtifactDataFromParent(itemTarget);
                if (childItem.IsEquipped())
                {
                    _player._ApplyItemMods(childItem, childItem.GetSlot(), true);
                }
            }

            bool SocketBonusToBeActivated = itemTarget.GemsFitSockets(); //current socketbonus state

            if (SocketBonusActivated ^ SocketBonusToBeActivated)         //if there was a change...
            {
                GetPlayer().ApplyEnchantment(itemTarget, EnchantmentSlot.Bonus, false);
                itemTarget.SetEnchantment(EnchantmentSlot.Bonus, SocketBonusToBeActivated ? itemTarget.GetTemplate().GetSocketBonus() : 0, 0, 0, GetPlayer().GetGUID());
                GetPlayer().ApplyEnchantment(itemTarget, EnchantmentSlot.Bonus, true);
                //it is not displayed, client has an inbuilt system to determine if the bonus is activated
            }

            GetPlayer().ToggleMetaGemsActive(slot, true);              //turn on all metagems (except for target item)

            GetPlayer().RemoveTradeableItem(itemTarget);
            itemTarget.ClearSoulboundTradeable(GetPlayer());           // clear tradeable flag

            itemTarget.SendUpdateSockets();
        }
示例#9
0
        void HandleSendMail(SendMail packet)
        {
            if (packet.Info.Attachments.Count > SharedConst.MaxClientMailItems)                      // client limit
            {
                GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.TooManyAttachments);
                return;
            }

            if (!CanOpenMailBox(packet.Info.Mailbox))
            {
                return;
            }

            if (string.IsNullOrEmpty(packet.Info.Target))
            {
                return;
            }

            Player player = GetPlayer();

            if (player.GetLevel() < WorldConfig.GetIntValue(WorldCfg.MailLevelReq))
            {
                SendNotification(CypherStrings.MailSenderReq, WorldConfig.GetIntValue(WorldCfg.MailLevelReq));
                return;
            }

            ObjectGuid receiverGuid = ObjectGuid.Empty;

            if (ObjectManager.NormalizePlayerName(ref packet.Info.Target))
            {
                receiverGuid = Global.CharacterCacheStorage.GetCharacterGuidByName(packet.Info.Target);
            }

            if (receiverGuid.IsEmpty())
            {
                Log.outInfo(LogFilter.Network, "Player {0} is sending mail to {1} (GUID: not existed!) with subject {2}" +
                            "and body {3} includes {4} items, {5} copper and {6} COD copper with StationeryID = {7}",
                            GetPlayerInfo(), packet.Info.Target, packet.Info.Subject, packet.Info.Body,
                            packet.Info.Attachments.Count, packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID);
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.RecipientNotFound);
                return;
            }

            if (packet.Info.SendMoney < 0)
            {
                GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.InternalError);
                Log.outWarn(LogFilter.Server, "Player {0} attempted to send mail to {1} ({2}) with negative money value (SendMoney: {3})",
                            GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.SendMoney);
                return;
            }

            if (packet.Info.Cod < 0)
            {
                GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.InternalError);
                Log.outWarn(LogFilter.Server, "Player {0} attempted to send mail to {1} ({2}) with negative COD value (Cod: {3})",
                            GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.Cod);
                return;
            }

            Log.outInfo(LogFilter.Network, "Player {0} is sending mail to {1} ({2}) with subject {3} and body {4}" +
                        "includes {5} items, {6} copper and {7} COD copper with StationeryID = {8}",
                        GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.Subject,
                        packet.Info.Body, packet.Info.Attachments.Count, packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID);

            if (player.GetGUID() == receiverGuid)
            {
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.CannotSendToSelf);
                return;
            }

            uint cost = (uint)(!packet.Info.Attachments.Empty() ? 30 * packet.Info.Attachments.Count : 30);  // price hardcoded in client

            long reqmoney = cost + packet.Info.SendMoney;

            // Check for overflow
            if (reqmoney < packet.Info.SendMoney)
            {
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotEnoughMoney);
                return;
            }

            if (!player.HasEnoughMoney(reqmoney) && !player.IsGameMaster())
            {
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotEnoughMoney);
                return;
            }

            Player receiver = Global.ObjAccessor.FindPlayer(receiverGuid);

            Team receiverTeam      = 0;
            byte mailsCount        = 0;                           //do not allow to send to one player more than 100 mails
            byte receiverLevel     = 0;
            uint receiverAccountId = 0;
            uint receiverBnetAccountId;

            if (receiver)
            {
                receiverTeam          = receiver.GetTeam();
                mailsCount            = (byte)receiver.GetMails().Count;
                receiverLevel         = (byte)receiver.GetLevel();
                receiverAccountId     = receiver.GetSession().GetAccountId();
                receiverBnetAccountId = receiver.GetSession().GetBattlenetAccountId();
            }
            else
            {
                CharacterCacheEntry characterInfo = Global.CharacterCacheStorage.GetCharacterCacheByGuid(receiverGuid);
                if (characterInfo != null)
                {
                    receiverTeam      = Player.TeamForRace(characterInfo.RaceId);
                    receiverLevel     = characterInfo.Level;
                    receiverAccountId = characterInfo.AccountId;
                }

                PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_COUNT);
                stmt.AddValue(0, receiverGuid.GetCounter());

                SQLResult result = DB.Characters.Query(stmt);
                if (!result.IsEmpty())
                {
                    mailsCount = (byte)result.Read <ulong>(0);
                }

                receiverBnetAccountId = Global.BNetAccountMgr.GetIdByGameAccount(receiverAccountId);
            }

            // do not allow to have more than 100 mails in mailbox.. mails count is in opcode byte!!! - so max can be 255..
            if (mailsCount > 100)
            {
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.RecipientCapReached);
                return;
            }

            // test the receiver's Faction... or all items are account bound
            bool accountBound = !packet.Info.Attachments.Empty();

            foreach (var att in packet.Info.Attachments)
            {
                Item item = player.GetItemByGuid(att.ItemGUID);
                if (item)
                {
                    ItemTemplate itemProto = item.GetTemplate();
                    if (itemProto == null || !itemProto.HasFlag(ItemFlags.IsBoundToAccount))
                    {
                        accountBound = false;
                        break;
                    }
                }
            }

            if (!accountBound && player.GetTeam() != receiverTeam && !HasPermission(RBACPermissions.TwoSideInteractionMail))
            {
                player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotYourTeam);
                return;
            }

            if (receiverLevel < WorldConfig.GetIntValue(WorldCfg.MailLevelReq))
            {
                SendNotification(CypherStrings.MailReceiverReq, WorldConfig.GetIntValue(WorldCfg.MailLevelReq));
                return;
            }

            List <Item> items = new();

            foreach (var att in packet.Info.Attachments)
            {
                if (att.ItemGUID.IsEmpty())
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.MailAttachmentInvalid);
                    return;
                }

                Item item = player.GetItemByGuid(att.ItemGUID);

                // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
                if (!item)
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.MailAttachmentInvalid);
                    return;
                }

                if (!item.CanBeTraded(true))
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.MailBoundItem);
                    return;
                }

                if (item.IsBoundAccountWide() && item.IsSoulBound() && player.GetSession().GetAccountId() != receiverAccountId)
                {
                    if (!item.IsBattlenetAccountBound() || player.GetSession().GetBattlenetAccountId() == 0 || player.GetSession().GetBattlenetAccountId() != receiverBnetAccountId)
                    {
                        player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.NotSameAccount);
                        return;
                    }
                }

                if (item.GetTemplate().HasFlag(ItemFlags.Conjured) || item.m_itemData.Expiration != 0)
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.MailBoundItem);
                    return;
                }

                if (packet.Info.Cod != 0 && item.IsWrapped())
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.CantSendWrappedCod);
                    return;
                }

                if (item.IsNotEmptyBag())
                {
                    player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.DestroyNonemptyBag);
                    return;
                }

                items.Add(item);
            }

            player.SendMailResult(0, MailResponseType.Send, MailResponseResult.Ok);

            player.ModifyMoney(-reqmoney);
            player.UpdateCriteria(CriteriaType.MoneySpentOnPostage, cost);

            bool needItemDelay = false;

            MailDraft draft = new(packet.Info.Subject, packet.Info.Body);

            SQLTransaction trans = new();

            if (!packet.Info.Attachments.Empty() || packet.Info.SendMoney > 0)
            {
                bool log = HasPermission(RBACPermissions.LogGmTrade);
                if (!packet.Info.Attachments.Empty())
                {
                    foreach (var item in items)
                    {
                        if (log)
                        {
                            Log.outCommand(GetAccountId(), "GM {0} ({1}) (Account: {2}) mail item: {3} (Entry: {4} Count: {5}) to player: {6} ({7}) (Account: {8})",
                                           GetPlayerName(), GetPlayer().GetGUID().ToString(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount(),
                                           packet.Info.Target, receiverGuid.ToString(), receiverAccountId);
                        }

                        item.SetNotRefundable(GetPlayer()); // makes the item no longer refundable
                        player.MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true);

                        item.DeleteFromInventoryDB(trans);     // deletes item from character's inventory
                        item.SetOwnerGUID(receiverGuid);
                        item.SetState(ItemUpdateState.Changed);
                        item.SaveToDB(trans);                  // recursive and not have transaction guard into self, item not in inventory and can be save standalone

                        draft.AddItem(item);
                    }

                    // if item send to character at another account, then apply item delivery delay
                    needItemDelay = player.GetSession().GetAccountId() != receiverAccountId;
                }

                if (log && packet.Info.SendMoney > 0)
                {
                    Log.outCommand(GetAccountId(), "GM {0} ({1}) (Account: {2}) mail money: {3} to player: {4} ({5}) (Account: {6})",
                                   GetPlayerName(), GetPlayer().GetGUID().ToString(), GetAccountId(), packet.Info.SendMoney, packet.Info.Target, receiverGuid.ToString(), receiverAccountId);
                }
            }

            // If theres is an item, there is a one hour delivery delay if sent to another account's character.
            uint deliver_delay = needItemDelay ? WorldConfig.GetUIntValue(WorldCfg.MailDeliveryDelay) : 0;

            // Mail sent between guild members arrives instantly
            Guild guild = Global.GuildMgr.GetGuildById(player.GetGuildId());

            if (guild)
            {
                if (guild.IsMember(receiverGuid))
                {
                    deliver_delay = 0;
                }
            }

            // don't ask for COD if there are no items
            if (packet.Info.Attachments.Empty())
            {
                packet.Info.Cod = 0;
            }

            // will delete item or place to receiver mail list
            draft.AddMoney((ulong)packet.Info.SendMoney).AddCOD((uint)packet.Info.Cod).SendMailTo(trans, new MailReceiver(receiver, receiverGuid.GetCounter()), new MailSender(player), string.IsNullOrEmpty(packet.Info.Body) ? MailCheckMask.Copied : MailCheckMask.HasBody, deliver_delay);

            player.SaveInventoryAndGoldToDB(trans);
            DB.Characters.CommitTransaction(trans);
        }
示例#10
0
        void HandleSellItem(SellItem packet)
        {
            if (packet.ItemGUID.IsEmpty())
            {
                return;
            }

            var pl = GetPlayer();

            Creature creature = pl.GetNPCIfCanInteractWith(packet.VendorGUID, NPCFlags.Vendor, NPCFlags2.None);

            if (creature == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleSellItemOpcode - {0} not found or you can not interact with him.", packet.VendorGUID.ToString());
                pl.SendSellError(SellResult.CantFindVendor, null, packet.ItemGUID);
                return;
            }

            if (creature.GetCreatureTemplate().FlagsExtra.HasFlag(CreatureFlagsExtra.NoSellVendor))
            {
                _player.SendSellError(SellResult.CantSellToThisMerchant, creature, packet.ItemGUID);
                return;
            }

            // remove fake death
            if (pl.HasUnitState(UnitState.Died))
            {
                pl.RemoveAurasByType(AuraType.FeignDeath);
            }

            Item pItem = pl.GetItemByGuid(packet.ItemGUID);

            if (pItem != null)
            {
                // prevent sell not owner item
                if (pl.GetGUID() != pItem.GetOwnerGUID())
                {
                    pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                    return;
                }

                // prevent sell non empty bag by drag-and-drop at vendor's item list
                if (pItem.IsNotEmptyBag())
                {
                    pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                    return;
                }

                // prevent sell currently looted item
                if (pl.GetLootGUID() == pItem.GetGUID())
                {
                    pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                    return;
                }

                // prevent selling item for sellprice when the item is still refundable
                // this probably happens when right clicking a refundable item, the client sends both
                // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
                if (pItem.IsRefundable())
                {
                    return; // Therefore, no feedback to client
                }
                // special case at auto sell (sell all)
                if (packet.Amount == 0)
                {
                    packet.Amount = pItem.GetCount();
                }
                else
                {
                    // prevent sell more items that exist in stack (possible only not from client)
                    if (packet.Amount > pItem.GetCount())
                    {
                        pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                        return;
                    }
                }

                ItemTemplate pProto = pItem.GetTemplate();
                if (pProto != null)
                {
                    if (pProto.GetSellPrice() > 0)
                    {
                        ulong money = pProto.GetSellPrice() * packet.Amount;

                        if (!_player.ModifyMoney((long)money)) // ensure player doesn't exceed gold limit
                        {
                            _player.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                            return;
                        }

                        _player.UpdateCriteria(CriteriaType.MoneyEarnedFromSales, money);
                        _player.UpdateCriteria(CriteriaType.SellItemsToVendors, 1);

                        if (packet.Amount < pItem.GetCount())               // need split items
                        {
                            Item pNewItem = pItem.CloneItem(packet.Amount, pl);
                            if (pNewItem == null)
                            {
                                Log.outError(LogFilter.Network, "WORLD: HandleSellItemOpcode - could not create clone of item {0}; count = {1}", pItem.GetEntry(), packet.Amount);
                                pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                                return;
                            }

                            pItem.SetCount(pItem.GetCount() - packet.Amount);
                            pl.ItemRemovedQuestCheck(pItem.GetEntry(), packet.Amount);
                            if (pl.IsInWorld)
                            {
                                pItem.SendUpdateToPlayer(pl);
                            }
                            pItem.SetState(ItemUpdateState.Changed, pl);

                            pl.AddItemToBuyBackSlot(pNewItem);
                            if (pl.IsInWorld)
                            {
                                pNewItem.SendUpdateToPlayer(pl);
                            }
                        }
                        else
                        {
                            pl.ItemRemovedQuestCheck(pItem.GetEntry(), pItem.GetCount());
                            pl.RemoveItem(pItem.GetBagSlot(), pItem.GetSlot(), true);
                            Item.RemoveItemFromUpdateQueueOf(pItem, pl);
                            pl.AddItemToBuyBackSlot(pItem);
                        }
                    }
                    else
                    {
                        pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
                    }
                    return;
                }
            }
            pl.SendSellError(SellResult.CantSellItem, creature, packet.ItemGUID);
            return;
        }
示例#11
0
        void HandlePetitionBuy(PetitionBuy packet)
        {
            // prevent cheating
            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.Petitioner, NPCFlags2.None);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandlePetitionBuyOpcode - {0} not found or you can't interact with him.", packet.Unit.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            uint charterItemID = GuildConst.CharterItemId;
            int  cost          = WorldConfig.GetIntValue(WorldCfg.CharterCostGuild);

            // do not let if already in guild.
            if (GetPlayer().GetGuildId() != 0)
            {
                return;
            }

            if (Global.GuildMgr.GetGuildByName(packet.Title))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameExists_S, packet.Title);
                return;
            }

            if (Global.ObjectMgr.IsReservedName(packet.Title) || !ObjectManager.IsValidCharterName(packet.Title))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameInvalid, packet.Title);
                return;
            }

            ItemTemplate pProto = Global.ObjectMgr.GetItemTemplate(charterItemID);

            if (pProto == null)
            {
                GetPlayer().SendBuyError(BuyResult.CantFindItem, null, charterItemID);
                return;
            }

            if (!GetPlayer().HasEnoughMoney(cost))
            {                                                       //player hasn't got enough money
                GetPlayer().SendBuyError(BuyResult.NotEnoughtMoney, creature, charterItemID);
                return;
            }

            List <ItemPosCount> dest = new List <ItemPosCount>();
            InventoryResult     msg  = GetPlayer().CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, charterItemID, pProto.GetBuyCount());

            if (msg != InventoryResult.Ok)
            {
                GetPlayer().SendEquipError(msg, null, null, charterItemID);
                return;
            }

            GetPlayer().ModifyMoney(-cost);
            Item charter = GetPlayer().StoreNewItem(dest, charterItemID, true);

            if (!charter)
            {
                return;
            }

            charter.SetPetitionId((uint)charter.GetGUID().GetCounter());
            charter.SetState(ItemUpdateState.Changed, GetPlayer());
            GetPlayer().SendNewItem(charter, 1, true, false);

            // a petition is invalid, if both the owner and the type matches
            // we checked above, if this player is in an arenateam, so this must be
            // datacorruption
            Petition petition = Global.PetitionMgr.GetPetitionByOwner(_player.GetGUID());

            if (petition != null)
            {
                // clear from petition store
                Global.PetitionMgr.RemovePetition(petition.PetitionGuid);
                Log.outDebug(LogFilter.Network, $"Invalid petition GUID: {petition.PetitionGuid.GetCounter()}");
            }

            // fill petition store
            Global.PetitionMgr.AddPetition(charter.GetGUID(), _player.GetGUID(), packet.Title, false);
        }
示例#12
0
        void HandlePetitionBuy(PetitionBuy packet)
        {
            // prevent cheating
            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.Petitioner);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandlePetitionBuyOpcode - {0} not found or you can't interact with him.", packet.Unit.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            uint charterItemID = GuildConst.CharterItemId;
            int  cost          = WorldConfig.GetIntValue(WorldCfg.CharterCostGuild);

            // do not let if already in guild.
            if (GetPlayer().GetGuildId() != 0)
            {
                return;
            }

            if (Global.GuildMgr.GetGuildByName(packet.Title))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameExists_S, packet.Title);
                return;
            }

            if (Global.ObjectMgr.IsReservedName(packet.Title) || !ObjectManager.IsValidCharterName(packet.Title))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameInvalid, packet.Title);
                return;
            }

            ItemTemplate pProto = Global.ObjectMgr.GetItemTemplate(charterItemID);

            if (pProto == null)
            {
                GetPlayer().SendBuyError(BuyResult.CantFindItem, null, charterItemID);
                return;
            }

            if (!GetPlayer().HasEnoughMoney(cost))
            {                                                       //player hasn't got enough money
                GetPlayer().SendBuyError(BuyResult.NotEnoughtMoney, creature, charterItemID);
                return;
            }

            List <ItemPosCount> dest = new List <ItemPosCount>();
            InventoryResult     msg  = GetPlayer().CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, charterItemID, pProto.GetBuyCount());

            if (msg != InventoryResult.Ok)
            {
                GetPlayer().SendEquipError(msg, null, null, charterItemID);
                return;
            }

            GetPlayer().ModifyMoney(-cost);
            Item charter = GetPlayer().StoreNewItem(dest, charterItemID, true);

            if (!charter)
            {
                return;
            }

            charter.SetUInt32Value(ItemFields.Enchantment, (uint)charter.GetGUID().GetCounter());
            // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
            // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
            charter.SetState(ItemUpdateState.Changed, GetPlayer());
            GetPlayer().SendNewItem(charter, 1, true, false);

            // a petition is invalid, if both the owner and the type matches
            // we checked above, if this player is in an arenateam, so this must be
            // datacorruption
            PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_BY_OWNER);

            stmt.AddValue(0, GetPlayer().GetGUID().GetCounter());
            SQLResult result = DB.Characters.Query(stmt);

            StringBuilder ssInvalidPetitionGUIDs = new StringBuilder();

            if (!result.IsEmpty())
            {
                do
                {
                    ssInvalidPetitionGUIDs.AppendFormat("'{0}', ", result.Read <uint>(0));
                } while (result.NextRow());
            }

            // delete petitions with the same guid as this one
            ssInvalidPetitionGUIDs.AppendFormat("'{0}'", charter.GetGUID().GetCounter());

            Log.outDebug(LogFilter.Network, "Invalid petition GUIDs: {0}", ssInvalidPetitionGUIDs.ToString());
            SQLTransaction trans = new SQLTransaction();

            trans.Append("DELETE FROM petition WHERE petitionguid IN ({0})", ssInvalidPetitionGUIDs.ToString());
            trans.Append("DELETE FROM petition_sign WHERE petitionguid IN ({0})", ssInvalidPetitionGUIDs.ToString());

            stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_PETITION);
            stmt.AddValue(0, GetPlayer().GetGUID().GetCounter());
            stmt.AddValue(1, charter.GetGUID().GetCounter());
            stmt.AddValue(2, packet.Title);
            trans.Append(stmt);

            DB.Characters.CommitTransaction(trans);
        }
示例#13
0
 public ItemStack(ItemTemplate template) : this(template, 1)
 {
 }
示例#14
0
 public ItemStack(ItemTemplate item, uint count)
 {
     this.item  = item;
     this.count = count;
 }