/// <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 PlayerLoginPacket playerLoginPacket)) { this.Logger.LogWarning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(playerLoginPacket.PacketType.ToByte()); message.AddUInt32(playerLoginPacket.CreatureId); message.AddByte(playerLoginPacket.GraphicsSpeed); message.AddByte(playerLoginPacket.CanReportBugs); message.AddByte(Math.Min((byte)0x01, playerLoginPacket.Player.PermissionsLevel)); if (playerLoginPacket.Player.PermissionsLevel > 0) { message.AddByte(OutgoingPacketType.GamemasterFlags.ToByte()); for (var i = 0; i < 32; i++) { // TODO: Actually send individual permissions flags message.AddByte(byte.MaxValue); } } }
/// <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(creatureSpeechPacket.SpeechType switch { // ChannelRed = 0x05, //Talk red on chat - #c // PrivateRed = 0x04, //Red private - @name@ text // ChannelOrange = 0x05, //Talk orange on text // ChannelRedAnonymous = 0x05, //Talk red anonymously on chat - #d // MonsterYell = 0x0E, //Yell orange SpeechType.Normal => 0x01, SpeechType.Whisper => 0x02, SpeechType.Yell => 0x03, SpeechType.Private => 0x04, SpeechType.ChannelYellow => 0x05, SpeechType.RuleViolationReport => 0x06, SpeechType.RuleViolationAnswer => 0x07, SpeechType.RuleViolationContinue => 0x08, SpeechType.Broadcast => 0x09, SpeechType.MonsterNormal => 0x0E, _ => 0x01, });
/// <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); }
/// <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 CreatureSkullPacket creatureSkullPacket)) { this.Logger.LogWarning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureSkullPacket.PacketType.ToByte()); message.AddUInt32(creatureSkullPacket.Creature.Id); message.AddByte(0x00); // creatureSkullPacket.Creature.Skull }
/// <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 SquarePacket squarePacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(squarePacket.PacketType.ToByte()); message.AddUInt32(squarePacket.OnCreatureId); message.AddByte((byte)squarePacket.Color); }
/// <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 CreatureHealthPacket creatureHealthPacket)) { this.Logger.LogWarning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureHealthPacket.PacketType.ToByte()); message.AddUInt32(creatureHealthPacket.Creature.Id); message.AddByte(creatureHealthPacket.Creature.Stats[CreatureStat.HitPoints].Percent); }
/// <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 CreatureLightPacket creatureLightPacket)) { this.Logger.Warning($"Invalid packet {packet.GetType().Name} routed to {this.GetType().Name}"); return; } message.AddByte(creatureLightPacket.PacketType.ToByte()); message.AddUInt32(creatureLightPacket.Creature.Id); message.AddByte(creatureLightPacket.Creature.EmittedLightLevel); message.AddByte(creatureLightPacket.Creature.EmittedLightColor); }
/// <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 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); }
public void NetworkMessage_AddUInt32Test() { const uint ValueToAdd = 123456789; INetworkMessage testMessage1 = this.SetupOutboundMessage(); Assert.IsNotNull(testMessage1); Assert.AreEqual(DefaultTestBufferOutgoingMessageCursor, testMessage1.Cursor); Assert.AreEqual(DefaultTestBufferOutgoingMessageLength, testMessage1.Length); // Add to the message testMessage1.AddUInt32(ValueToAdd); var asInboundMessage = ConvertToInboundMessage(testMessage1); // Leverage other NetworkMessage methods, which is fine as they have their own tests. var valueRead = asInboundMessage.GetUInt32(); Assert.AreEqual(ValueToAdd, valueRead); }