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); }
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); } }
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); }
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); } }
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); } }
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(); }
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); }
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; }
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); }
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); }
public ItemStack(ItemTemplate template) : this(template, 1) { }
public ItemStack(ItemTemplate item, uint count) { this.item = item; this.count = count; }