public static void Send_SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA(Character chr) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0)) { chr.Send(packet); } }
public static void SendInBounds(Character duelist) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_DUEL_INBOUNDS,4)) { duelist.Send(packet); } }
public void SendSpontaneousUpdate(Character receiver, bool visible, params UpdateFieldId[] indices) { var highestIndex = 0; foreach (var index in indices) { if (index.RawId > highestIndex) { highestIndex = index.RawId; } } var mask = new UpdateMask(highestIndex); using (var packet = new UpdatePacket(1024)) { packet.Position = 4; // jump over header packet.Write(1); // Update Count packet.Write((byte)UpdateType.Values); EntityId.WritePacked(packet); WriteSpontaneousUpdate(mask, packet, receiver, indices, visible); receiver.Send(packet); } }
public static void SendCountdown(Character duelist, uint millis) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_DUEL_COUNTDOWN, 4)) { packet.Write(millis); duelist.Send(packet); } }
public static void SendTitleEarned(Character character, CharacterTitleEntry titleEntry, bool lost) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_TITLE_EARNED, 4 + 4)) { packet.WriteUInt((uint) titleEntry.BitIndex); packet.WriteUInt(lost ? 0 : 1); character.Send(packet); } }
public static void SendOutOfBounds(Character duelist, uint cancelDelayMillis) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_DUEL_OUTOFBOUNDS, 4)) { packet.Write(cancelDelayMillis); duelist.Send(packet); } }
public void SendOutOfRangeUpdate(Character receiver, HashSet <WorldObject> worldObjects) { using (var packet = new UpdatePacket(1024)) { packet.Position = 4; // jump over header packet.Write(1); // Update Count packet.Write((byte)UpdateType.OutOfRange); packet.Write(worldObjects.Count); foreach (var worldObject in worldObjects) { worldObject.EntityId.WritePacked(packet); } receiver.Send(packet); } }
/// <summary> /// Sends the quest update complete. /// </summary> /// <param name="chr">The character.</param> public static void SendQuestUpdateComplete(Character chr, uint questId) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_QUESTUPDATE_COMPLETE)) { packet.Write(questId); chr.Send(packet); } }
/// <summary> /// Sends the quest update failed timer. /// </summary> /// <param name="qst">The QST.</param> /// <param name="chr">The character</param> public static void SendQuestUpdateFailedTimer(Character chr, Quest qst) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_QUESTUPDATE_FAILEDTIMER)) { packet.Write(qst.Template.Id); chr.Send(packet); } }
public static void SendQuestCompletedQueryResponse(Character chr) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4)) { packet.Write(chr.QuestLog.FinishedQuests.Count); foreach (var entry in chr.QuestLog.FinishedQuests) { packet.Write(entry); } chr.Send(packet); } }
/// <summary> /// Sends the quest invalid. /// </summary> /// <param name="chr">The character.</param> /// <param name="reason">The reason.</param> public static void SendQuestInvalid(Character chr, QuestInvalidReason reason) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_QUESTGIVER_QUEST_INVALID, 4)) { packet.Write((int)reason); chr.Send(packet); } }
public static void SendStatusEnqueued(Character chr, int index, BattlegroundRelation relation, BattlegroundQueue queue) { var status = BattlegroundStatus.Enqueued; using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_BATTLEFIELD_STATUS)) { packet.Write(index); var bgId = queue.Template.Id; // 64-bit guid start packet.Write((byte)ArenaType.None); packet.Write((byte)1); // affects level range calculation? packet.Write((uint)bgId); packet.Write((ushort)8080); // 64-bit guid stop packet.Write((byte)0); // since 3.3 packet.Write((byte)0); // since 3.3 packet.Write(queue.InstanceId); // instance id packet.Write(false); // bool isRatedMatch packet.Write((int)status); packet.Write(queue.AverageWaitTime); // avg wait time for queue, in ms packet.Write((int)relation.QueueTime.TotalMilliseconds); // time in the queue, also in ms chr.Send(packet); } }
public static void SendBankSlotResult(Character chr, BuyBankBagResponse response) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_BUY_BANK_SLOT_RESULT, 4)) { packet.Write((uint)response); chr.Send(packet); } }
public static void SendPetGUIDs(Character chr) { if (chr.ActivePet == null) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_PET_GUIDS, 12)) { packet.Write(0); // list count chr.Send(packet); } } else { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_PET_GUIDS, 12)) { packet.Write(1); // list count packet.Write(chr.ActivePet.EntityId); chr.Send(packet); } } }
public static void SendDungeonDifficulty(Character chr) { using (var packet = new RealmPacketOut(RealmServerOpCode.MSG_SET_DUNGEON_DIFFICULTY, 12)) { var group = chr.Group; if (group != null && !group.Flags.HasFlag(GroupFlags.Raid)) { packet.Write(group.DungeonDifficulty); packet.Write(1); // val packet.Write(1); // isingroup } else // this is wrong? one packet def should be enough { packet.Write((int)chr.Record.DungeonDifficulty); packet.Write(1); packet.Write(0); } chr.Send(packet); } }
/// <summary> /// Sends spell modifier update /// </summary> public static void SendSpellModifier(Character chr, byte groupBitNumber, SpellModifierType type, int amount, bool isPercent) { var opcode = isPercent ? RealmServerOpCode.SMSG_SET_PCT_SPELL_MODIFIER : RealmServerOpCode.SMSG_SET_FLAT_SPELL_MODIFIER; using (var packet = new RealmPacketOut(opcode, 6)) { packet.Write(groupBitNumber); packet.Write((byte) type); packet.Write(amount); chr.Send(packet); } }
/// <summary> /// Parses any incoming whispers. /// </summary> /// <param name="type">the type of chat message indicated by the client</param> /// <param name="language">the chat language indicated by the client</param> /// <param name="packet">the actual chat message packet</param> private static void WhisperParser(Character sender, ChatMsgType type, ChatLanguage language, RealmPacketIn packet) { var recipient = packet.ReadCString(); var msg = ReadMessage(packet); if (msg.Length == 0) return; if (RealmCommandHandler.HandleCommand(sender, msg, sender.Target as Character)) return; var targetChr = World.GetCharacter(recipient, false); if (targetChr == null) { SendChatPlayerNotFoundReply(sender.Client, recipient); return; } if (targetChr.Faction.Group != sender.Faction.Group) { SendChatPlayerWrongTeamReply(sender.Client); return; } if (targetChr.IsIgnoring(sender)) { using (var packetOut = CreateCharChatMessage(ChatMsgType.Ignored, ChatLanguage.Universal, targetChr, sender, null, msg)) { sender.Send(packetOut); } } else { using (var packetOut = CreateCharChatMessage(ChatMsgType.Whisper, ChatLanguage.Universal, sender, targetChr, null, msg)) { targetChr.Send(packetOut); } } using (var packetOut = CreateCharChatMessage(ChatMsgType.MsgReply, ChatLanguage.Universal, targetChr, targetChr, null, msg, sender.ChatTag)) { sender.Send(packetOut); } // handle afk/dnd situations if (targetChr.IsAFK) { using (var packetOut = CreateCharChatMessage(ChatMsgType.AFK, ChatLanguage.Universal, targetChr, sender, null, targetChr.AFKReason, targetChr.ChatTag)) { sender.Send(packetOut); } } if (targetChr.IsDND) { using (var packetOut = CreateCharChatMessage(ChatMsgType.DND, ChatLanguage.Universal, targetChr, sender, null, string.Empty, targetChr.ChatTag)) { sender.Send(packetOut); } } }
/// <summary> /// Forces the client to start or update a cooldown timer on the given single spell /// (mostly important for certain talents and item spells that don't automatically start cooling down) /// </summary> public static void SendCooldownUpdate(Character chr, SpellId spellId) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_COOLDOWN_EVENT, 12)) { packet.WriteUInt((uint)spellId); chr.EntityId.WritePacked(packet); chr.Send(packet); } }
public static void SendTrainerList(this NPC trainer, Character chr, IEnumerable<TrainerSpellEntry> spells, string msg) { using ( var packet = new RealmPacketOut(RealmServerOpCode.SMSG_TRAINER_LIST, 8 + 4 + 4 + (30 * 38) + msg.Length + 1)) { packet.Write(trainer.EntityId); packet.Write((uint)trainer.TrainerEntry.TrainerType); var countPos = packet.Position; packet.Position += 4; var spellCount = 0; foreach (var trainerSpell in spells) { if (!chr.CanLearn(trainerSpell)) { continue; } var spell = trainerSpell.Spell; if (spell.IsTeachSpell) { spell = spell.LearnSpell; } //packet.Position = offset + (spell.Index * entryLength); packet.Write(trainerSpell.Spell.Id); packet.Write((byte)trainerSpell.GetTrainerSpellState(chr)); packet.Write(trainerSpell.GetDiscountedCost(chr, trainer)); packet.Write(spell.Talent != null ? 1u : 0u); // talent cost packet.Write(trainerSpell.Spell.IsProfession && trainerSpell.Spell.TeachesApprenticeAbility ? 1 : 0); // Profession cost packet.Write((byte)trainerSpell.RequiredLevel); packet.Write((uint)trainerSpell.RequiredSkillId); packet.Write(trainerSpell.RequiredSkillAmount); packet.Write((uint)trainerSpell.RequiredSpellId); // The following are infrequent Ids of some sort - Possibly spell replacements? packet.Write(0u); packet.Write(0u); ++spellCount; } packet.Write(msg); packet.Position = countPos; packet.Write(spellCount); chr.Send(packet); } }
/// <summary> /// Send the vendor's list of items for sale to the client. /// *All allowable race and class checks should be done prior to calling this method. /// *All checks on number-limited items should also be done prior to calling this method. /// *This method can handle up to 256 items per vendor. If you try to send more items than that, /// this method will send only the first 256. /// </summary> /// <param name="client">The client to send the packet to.</param> /// <param name="itemsForSale">An array of items to send to the client.</param> public static void SendVendorInventoryList(Character buyer, NPC vendor, List<VendorItemEntry> itemsForSale) { var numItems = (itemsForSale.Count <= 0xFF) ? itemsForSale.Count : 0xFF; using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_LIST_INVENTORY, 10 + (28 * numItems))) { packet.Write(vendor.EntityId); packet.Write((byte)numItems); if (numItems == 0) { packet.Write((byte)VendorInventoryError.NoInventory); } else { for (var i = 0; i < numItems; ++i) { // Write in the item number (1 - 256) packet.Write(i + 1); var item = itemsForSale[i]; var price = buyer.Reputations.GetDiscountedCost(vendor.Faction.ReputationIndex, item.Template.BuyPrice); packet.Write(item.Template.Id); packet.Write(item.Template.DisplayId); packet.Write(item.RemainingStockAmount); packet.Write(price); packet.Write(item.Template.MaxDurability); packet.Write(item.BuyStackSize); packet.Write(item.ExtendedCostId); } } buyer.Send(packet); } }
public static void SendQuestLogFull(Character chr) { using (var pckt = new RealmPacketOut(RealmServerOpCode.SMSG_QUESTLOG_FULL)) { chr.Send(pckt); } }
/// <summary> /// Sends any kind of extra command-bar to control other entities, such as NPCs, vehicles etc /// </summary> /// <param name="owner"></param> //public static void SendSpells(Character owner, NPC npc, uint duration, // PetAttackMode attackMode, PetAction action, PetFlags flags, // PetActionEntry[] petActions, // PetSpell[] spells) public static void SendSpells(Character owner, NPC pet, PetAction currentAction) { // TODO: Cooldowns var record = pet.PetRecord; var mode = pet.Entry.Type == CreatureType.NonCombatPet ? PetAttackMode.Passive : PetAttackMode.Defensive; var flags = PetFlags.None; uint[] actions = null; if(record != null) { mode = record.AttackMode; flags = record.Flags; actions = record.ActionButtons; } if (actions == null) actions = pet.BuildPetActionBar(); using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_PET_SPELLS, 20 + (PetConstants.PetActionCount * 4) + 1 + (pet.Spells.Count) + 1 + (0))) { packet.Write(pet.EntityId); packet.Write((ushort)pet.Entry.FamilyId); packet.Write(pet.RemainingDecayDelayMillis); // duration packet.Write((byte)mode); packet.Write((byte)currentAction); packet.Write((ushort)flags); for (var i = 0; i < PetConstants.PetActionCount; i++) { var action = actions[i]; packet.Write(action); } var spellPos = packet.Position; ++packet.Position; var spellCount = 0; foreach (var spell in pet.Spells) { if (!spell.IsPassive) { packet.Write((ushort)spell.Id); packet.Write((ushort)PetSpellState.Enabled); ++spellCount; } } packet.Write((byte)0); // TODO: Cooldowns packet.Position = spellPos; packet.Write((byte)spellCount); owner.Send(packet); } }
public static void SendQuestPushResult(Character receiver, QuestPushResponse qpr, Character giver) { using (var pckt = new RealmPacketOut(RealmServerOpCode.MSG_QUEST_PUSH_RESULT)) { pckt.Write(receiver.EntityId); pckt.Write((byte)qpr); giver.Send(pckt); } }
public static void SendStatusActive(Character chr, Battleground bg, int queueIndex) { var status = BattlegroundStatus.Active; var side = chr.FactionGroup.GetBattlegroundSide(); using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_BATTLEFIELD_STATUS)) { packet.Write(queueIndex); var bgId = bg.Template.Id; // 64-bit guid start packet.Write((byte)ArenaType.None); packet.Write((byte)1); // affects level range calculation? packet.Write((uint)bgId); packet.Write((ushort)8080); // 64-bit guid stop packet.Write((byte)0); // since 3.3 packet.Write((byte)0); // since 3.3 packet.Write(bg.InstanceId); // instance id packet.Write((byte)0); // bool isRatedMatch packet.Write((int)status); packet.Write((int)bg.Id); // the number of milliseconds before the Battlefield will close after a battle is finished. // This is 0 before the battle is finished packet.Write(bg.RemainingShutdownDelay); // start time, in ms. clientGetTickCount - this = instance runtime packet.Write(bg.RuntimeMillis); packet.Write((byte)side); // arena faction - 0 or 1 chr.Send(packet); } }
public static void SendBattlefieldList(Character chr, GlobalBattlegroundQueue queue) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_BATTLEFIELD_LIST)) { var fromGUI = true; packet.Write((long)0); packet.Write(fromGUI); // since 3.1.1 packet.Write((uint)queue.Template.Id); packet.Write((byte)queue.BracketId); // BracketId packet.Write((byte)0); // since 3.3 var pos = packet.Position; packet.Position += 4; var count = 0; for (var i = 0; i < queue.Instances.Count; i++) { var bg = queue.Instances[i]; if (chr.Role.IsStaff || bg.CanEnter(chr)) { packet.Write(bg.InstanceId); count++; } } packet.Position = pos; packet.Write(count); chr.Send(packet); } }
public void SendOutOfRangeUpdate(Character receiver, HashSet<WorldObject> worldObjects) { using (var packet = new UpdatePacket(1024)) { packet.Position = 4; // jump over header packet.Write(1); // Update Count packet.Write((byte)UpdateType.OutOfRange); packet.Write(worldObjects.Count); foreach (var worldObject in worldObjects) { worldObject.EntityId.WritePacked(packet); } receiver.Send(packet); } }
public static void SendStatusInvited(Character chr, int inviteTimeout) { var status = BattlegroundStatus.Preparing; var invite = chr.Battlegrounds.Invitation; using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_BATTLEFIELD_STATUS)) { packet.Write(invite.QueueIndex); var bg = invite.Team.Battleground; var bgId = bg.Template.Id; // 64-bit guid start packet.Write((byte)ArenaType.None); packet.Write((byte)1); // affects level range calculation? packet.Write((uint)bgId); packet.Write((ushort)8080); // 64-bit guid stop packet.Write((byte)0); // since 3.3 packet.Write((byte)0); // since 3.3 packet.Write(bg.InstanceId); // instance id packet.Write((byte)chr.FactionGroup.GetBattlegroundSide()); // bool isRatedMatch packet.Write((int)status); packet.Write((int)bg.Id); packet.Write(inviteTimeout); chr.Send(packet); } }
/// <summary> /// Sends any kind of extra command-bar to control other entities, such as NPCs, vehicles etc /// </summary> /// <param name="owner"></param> //public static void SendSpells(Character owner, NPC npc, uint duration, // PetAttackMode attackMode, PetAction action, PetFlags flags, // PetActionEntry[] petActions, // PetSpell[] spells) public static void SendSpells(Character owner, NPC pet, PetAction currentAction) { // TODO: Cooldowns var record = pet.PetRecord; using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_PET_SPELLS, 20 + (PetConstants.PetActionCount * 4) + 1 + (pet.Spells.Count) + 1 + (0))) { packet.Write(pet.EntityId); packet.Write((ushort)pet.Entry.FamilyId); //packet.Write((ushort)0); packet.Write(pet.RemainingDecayDelayMillis); // duration packet.Write((byte)record.AttackMode); packet.Write((byte)currentAction); packet.Write((ushort)record.Flags); var actions = record.ActionButtons; for (var i = 0; i < PetConstants.PetActionCount; i++) { var action = actions[i]; packet.Write(action); } var spellPos = packet.Position; ++packet.Position; var spellCount = 0; foreach (var spell in pet.Spells) { if (!spell.IsPassive) { packet.Write(spell.Id | ((uint)PetSpellState.Enabled << 24)); ++spellCount; } } packet.Write((byte)0); // TODO: Cooldowns packet.Position = spellPos; packet.Write((byte)spellCount); owner.Send(packet); } }
public static void SendAttackSwingNotInRange(Character chr) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_ATTACKSWING_NOTINRANGE)) { chr.Send(packet); } }
public static void SendPlayerPossessedPetSpells(Character owner, Character possessed) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_PET_SPELLS, 20 + (PetConstants.PetActionCount * 4) + 1 + (0) + 1 + (0))) { packet.Write(possessed.EntityId); packet.Write((ushort) CreatureFamilyId.None); packet.Write(0); // duration packet.Write((byte) PetAttackMode.Passive); packet.Write((byte) PetAction.Stay); packet.Write((ushort) PetFlags.None); var action = new PetActionEntry { Action = PetAction.Attack, Type = PetActionType.SetAction }.Raw; packet.Write(action); for (var i = 1; i < PetConstants.PetActionCount; i++) { action = new PetActionEntry { Type = PetActionType.SetAction }.Raw; packet.Write(action); } packet.Write((byte) 0); // No Spells packet.Write((byte) 0); // No Cooldowns owner.Send(packet); } }
/// <summary> /// Sends the Item's PushResult (required after adding items). /// </summary> public static void SendItemPushResult(Character owner, Item item, ItemTemplate templ, int amount, ItemReceptionType reception) { bool isStacked; int contSlot; uint propertySeed, randomPropid; if (item != null) { contSlot = item.Container.Slot; isStacked = item.Amount != amount; // item.Amount == amount means that it was not added to an existing stack propertySeed = item.PropertySeed; randomPropid = item.RandomPropertiesId; } else { contSlot = BaseInventory.INVALID_SLOT; isStacked = true; // we did not have an item -> stacked propertySeed = 0; randomPropid = 0; } using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_ITEM_PUSH_RESULT, 45)) { packet.Write(owner.EntityId); packet.Write((ulong)reception); //packet.Write(received ? 1 : 0); // 0 = "You looted...", 1 = "You received..." //packet.Write(isNew ? 1 : 0); // 0 = "You received/looted...", 1 = "You created..." packet.Write(1); // log message packet.Write((byte)contSlot); packet.Write(isStacked ? -1 : item.Slot); packet.Write(templ.Id); packet.Write(propertySeed); packet.Write(randomPropid); packet.Write(amount); // amount added packet.Write(owner.Inventory.GetAmount(templ.ItemId)); // amount of that type of item in inventory owner.Send(packet); } }