Example #1
0
        void HandleOpenItem(OpenItem packet)
        {
            Player player = GetPlayer();

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

            // additional check, client outputs message on its own
            if (!player.IsAlive())
            {
                player.SendEquipError(InventoryResult.PlayerDead);
                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.HasFlag(ItemFlags.HasLoot) && !item.IsWrapped())
            {
                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.IsWrapped())// wrapped?
            {
                PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM);
                stmt.AddValue(0, item.GetGUID().GetCounter());
                _queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt)
                                            .WithCallback(result => HandleOpenWrappedItemCallback(item.GetPos(), item.GetGUID(), result)));
            }
            else
            {
                player.SendLoot(item.GetGUID(), LootType.Corpse);
            }
        }
Example #2
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.GetFlags().HasAnyFlag(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();
        }
Example #3
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);
            }
        }