/// <summary> /// Adds an <see cref="Outfit"/>'s description to the message. /// </summary> /// <param name="message">The message to add the outfit to.</param> /// <param name="outfit">The outfit to add.</param> public static void AddOutfit(this INetworkMessage message, Outfit outfit) { // Add creature outfit message.AddUInt16(outfit.Id); if (outfit.Id > 0) { message.AddByte(outfit.Head); message.AddByte(outfit.Body); message.AddByte(outfit.Legs); message.AddByte(outfit.Feet); } else { message.AddUInt16(outfit.ItemIdLookAlike); } }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is CreatureSpeedChangePacket creatureSpeedChangePacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureSpeedChangePacket.PacketType); message.AddUInt32(creatureSpeedChangePacket.Creature.Id); message.AddUInt16(creatureSpeedChangePacket.Creature.Speed); }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is CharacterListPacket characterListPacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(characterListPacket.PacketType); message.AddByte((byte)characterListPacket.Characters.Count()); foreach (var character in characterListPacket.Characters) { message.AddString(character.Name); message.AddString(character.World); message.AddBytes(character.Ip); message.AddUInt16(character.Port); } message.AddUInt16(characterListPacket.PremiumDaysLeft); }
/// <summary> /// Add a <see cref="ICreature"/>'s description to the message. /// </summary> /// <param name="message">The message to add the creature description to.</param> /// <param name="creature">The creature to describe and add.</param> /// <param name="asKnown">A value indicating whether this creature is known.</param> /// <param name="creatureToRemoveId">The id of another creature to replace if the client buffer is known to be full.</param> public static void AddCreature(this INetworkMessage message, ICreature creature, bool asKnown, uint creatureToRemoveId) { if (asKnown) { message.AddByte((byte)OutgoingGamePacketType.AddKnownCreature); // known message.AddByte(0x00); message.AddUInt32(creature.Id); } else { message.AddByte((byte)OutgoingGamePacketType.AddUnknownCreature); // unknown message.AddByte(0x00); message.AddUInt32(creatureToRemoveId); message.AddUInt32(creature.Id); message.AddString(creature.Name); } message.AddByte(Convert.ToByte(Math.Min(100, creature.Hitpoints * 100 / creature.MaxHitpoints))); // health bar, needs a percentage. message.AddByte(Convert.ToByte(creature.Direction.GetClientSafeDirection())); if (creature.IsInvisible) { message.AddUInt16(0x00); message.AddUInt16(0x00); } else { message.AddOutfit(creature.Outfit); } message.AddByte(creature.EmittedLightLevel); message.AddByte(creature.EmittedLightColor); message.AddUInt16(creature.Speed); message.AddByte(creature.Skull); message.AddByte(creature.Shield); }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is CreatureTurnedPacket creatureTurnedPacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureTurnedPacket.PacketType); message.AddLocation(creatureTurnedPacket.Creature.Location); message.AddByte(creatureTurnedPacket.StackPosition); message.AddUInt16(creatureTurnedPacket.Creature.TypeId); message.AddUInt32(creatureTurnedPacket.Creature.Id); message.AddByte((byte)creatureTurnedPacket.Creature.Direction); }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is CreatureSpeechPacket creatureSpeechPacket)) { this.Logger.LogWarning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureSpeechPacket.PacketType.ToByte()); message.AddUInt32(0); message.AddString(creatureSpeechPacket.SenderName); message.AddByte((byte)creatureSpeechPacket.SpeechType); switch (creatureSpeechPacket.SpeechType) { case SpeechType.Say: case SpeechType.Whisper: case SpeechType.Yell: case SpeechType.MonsterSay: // case SpeechType.MonsterYell: message.AddLocation(creatureSpeechPacket.Location); break; // case SpeechType.ChannelRed: // case SpeechType.ChannelRedAnonymous: // case SpeechType.ChannelOrange: case SpeechType.ChannelYellow: // case SpeechType.ChannelWhite: message.AddUInt16((ushort)creatureSpeechPacket.Channel); break; case SpeechType.RuleViolationReport: message.AddUInt32(creatureSpeechPacket.Time); break; default: break; } message.AddString(creatureSpeechPacket.Text); }
public void NetworkMessage_AddUInt16Test() { const ushort ValueToAdd = 12345; INetworkMessage testMessage1 = this.SetupOutboundMessage(); Assert.IsNotNull(testMessage1); Assert.AreEqual(DefaultTestBufferOutgoingMessageCursor, testMessage1.Cursor); Assert.AreEqual(DefaultTestBufferOutgoingMessageLength, testMessage1.Length); // Add to the message testMessage1.AddUInt16(ValueToAdd); var asInboundMessage = ConvertToInboundMessage(testMessage1); // Leverage other NetworkMessage methods, which is fine as they have their own tests. var valueRead = asInboundMessage.GetUInt16(); Assert.AreEqual(ValueToAdd, valueRead); }
/// <summary> /// Adds an <see cref="IItem"/>'s description to a message. /// </summary> /// <param name="message">The message to add the item description to.</param> /// <param name="item">The item to describe and add.</param> public static void AddItem(this INetworkMessage message, IItem item) { if (item == null) { // TODO: log this. Console.WriteLine("Add: Null item passed."); return; } message.AddUInt16(item.Type.ClientId); if (item.IsCumulative) { message.AddByte(item.Amount); } else if (item.IsLiquidPool || item.IsLiquidSource || item.IsLiquidContainer) { message.AddByte(item.LiquidType); } }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is ContainerOpenPacket containerOpenPacket)) { this.Logger.LogWarning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(containerOpenPacket.PacketType.ToByte()); message.AddByte(containerOpenPacket.ContainerId); message.AddUInt16(containerOpenPacket.TypeId); message.AddString(containerOpenPacket.Name); message.AddByte(containerOpenPacket.Volume); message.AddByte(Convert.ToByte(containerOpenPacket.HasParent ? 0x01 : 0x00)); message.AddByte(Convert.ToByte(containerOpenPacket.Contents.Count)); foreach (var item in containerOpenPacket.Contents) { message.AddItem(item); } }
/// <summary> /// Writes a packet to the given <see cref="INetworkMessage"/>. /// </summary> /// <param name="packet">The packet to write.</param> /// <param name="message">The message to write into.</param> public override void WriteToMessage(IOutboundPacket packet, ref INetworkMessage message) { if (!(packet is PlayerStatsPacket playerStatsPacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } ushort hitpoints = Math.Min(ushort.MaxValue, (ushort)playerStatsPacket.Player.Stats[CreatureStat.HitPoints].Current); ushort maxHitpoints = Math.Min(ushort.MaxValue, (ushort)playerStatsPacket.Player.Stats[CreatureStat.HitPoints].Maximum); ushort manapoints = Math.Min(ushort.MaxValue, (ushort)playerStatsPacket.Player.Stats[CreatureStat.ManaPoints].Current); ushort maxManapoints = Math.Min(ushort.MaxValue, (ushort)playerStatsPacket.Player.Stats[CreatureStat.ManaPoints].Maximum); ushort capacity = Convert.ToUInt16(Math.Min(ushort.MaxValue, (ushort)playerStatsPacket.Player.Stats[CreatureStat.CarryStrength].Current)); ICombatant combatantPlayer = playerStatsPacket.Player as ICombatant; // Fail off by sending dummy data if the player for some reason is not a combatant. // Experience: 7.7x Client debugs after 0x7FFFFFFF (2,147,483,647) exp uint experience = combatantPlayer != null?Math.Min(0x7FFFFFFF, Convert.ToUInt32(combatantPlayer.Skills[SkillType.Experience].Count)) : 0; ushort expLevel = (ushort)(combatantPlayer != null ? Math.Max(1, Math.Min(ushort.MaxValue, combatantPlayer.Skills[SkillType.Experience].Level)) : 1); byte expPercentage = (byte)(combatantPlayer != null ? combatantPlayer.Skills[SkillType.Experience].Percent : 0); byte magicLevel = (byte)(combatantPlayer != null ? Math.Min(byte.MaxValue, combatantPlayer.Skills[SkillType.Magic].Level) : 0); byte magicLevelPercentage = (byte)(combatantPlayer != null ? combatantPlayer.Skills[SkillType.Magic].Percent : 0); message.AddByte(playerStatsPacket.PacketType.ToByte()); message.AddUInt16(hitpoints); message.AddUInt16(maxHitpoints); message.AddUInt16(capacity); message.AddUInt32(experience); message.AddUInt16(expLevel); message.AddByte(expPercentage); message.AddUInt16(manapoints); message.AddUInt16(maxManapoints); message.AddByte(magicLevel); message.AddByte(magicLevelPercentage); message.AddByte(playerStatsPacket.Player.SoulPoints); }
/// <summary> /// Adds a <see cref="Location"/>'s description to the message. /// </summary> /// <param name="message">The message to add the location to.</param> /// <param name="location">The location to add.</param> public static void AddLocation(this INetworkMessage message, Location location) { message.AddUInt16((ushort)location.X); message.AddUInt16((ushort)location.Y); message.AddByte((byte)location.Z); }