diff --git a/docs/Packets/C3-F3-03-CharacterInformationExtended_by-server.md b/docs/Packets/C3-F3-03-CharacterInformationExtended_by-server.md index af4ababc7..d2a263db0 100644 --- a/docs/Packets/C3-F3-03-CharacterInformationExtended_by-server.md +++ b/docs/Packets/C3-F3-03-CharacterInformationExtended_by-server.md @@ -13,7 +13,7 @@ The characters enters the game world. | Index | Length | Data Type | Value | Description | |-------|--------|-----------|-------|-------------| | 0 | 1 | Byte | 0xC3 | [Packet type](PacketTypes.md) | -| 1 | 1 | Byte | 96 | Packet header - length of the packet | +| 1 | 1 | Byte | 92 | Packet header - length of the packet | | 2 | 1 | Byte | 0xF3 | Packet header - packet type identifier | | 3 | 1 | Byte | 0x03 | Packet header - sub packet type identifier | | 4 | 1 | Byte | | X | @@ -46,6 +46,7 @@ The characters enters the game world. | 84 | 2 | ShortLittleEndian | | MagicSpeed | | 86 | 2 | ShortLittleEndian | | MaximumAttackSpeed | | 88 | 1 | Byte | | InventoryExtensions | +| 90 | 2 | ShortLittleEndian | | Resets | ### CharacterHeroState Enum diff --git a/src/GameServer/RemoteView/Character/UpdateCharacterStatsExtendedPlugIn.cs b/src/GameServer/RemoteView/Character/UpdateCharacterStatsExtendedPlugIn.cs index 346de1d2f..dce9a6331 100644 --- a/src/GameServer/RemoteView/Character/UpdateCharacterStatsExtendedPlugIn.cs +++ b/src/GameServer/RemoteView/Character/UpdateCharacterStatsExtendedPlugIn.cs @@ -69,7 +69,8 @@ await connection.SendCharacterInformationExtendedAsync( (ushort)this._player.Attributes[Stats.AttackSpeed], (ushort)this._player.Attributes[Stats.MagicSpeed], (ushort)maxAttackSpeed, - (byte)this._player.SelectedCharacter.InventoryExtensions) + (byte)this._player.SelectedCharacter.InventoryExtensions, + (ushort)this._player.Attributes[Stats.Resets]) .ConfigureAwait(false); if (this._player.SelectedCharacter.CharacterClass!.IsMasterClass) diff --git a/src/Network/Packets/ServerToClient/ConnectionExtensions.cs b/src/Network/Packets/ServerToClient/ConnectionExtensions.cs index df5bd00e6..c953fa6cb 100644 --- a/src/Network/Packets/ServerToClient/ConnectionExtensions.cs +++ b/src/Network/Packets/ServerToClient/ConnectionExtensions.cs @@ -3385,11 +3385,12 @@ int WritePacket() /// The magic speed. /// The maximum attack speed. /// The inventory extensions. + /// The resets. /// /// Is sent by the server when: After the character was selected by the player and entered the game. /// Causes reaction on client side: The characters enters the game world. /// - public static async ValueTask SendCharacterInformationExtendedAsync(this IConnection? connection, byte @x, byte @y, ushort @mapId, ulong @currentExperience, ulong @experienceForNextLevel, ushort @levelUpPoints, ushort @strength, ushort @agility, ushort @vitality, ushort @energy, ushort @leadership, uint @currentHealth, uint @maximumHealth, uint @currentMana, uint @maximumMana, uint @currentShield, uint @maximumShield, uint @currentAbility, uint @maximumAbility, uint @money, CharacterHeroState @heroState, CharacterStatus @status, ushort @usedFruitPoints, ushort @maxFruitPoints, ushort @usedNegativeFruitPoints, ushort @maxNegativeFruitPoints, ushort @attackSpeed, ushort @magicSpeed, ushort @maximumAttackSpeed, byte @inventoryExtensions) + public static async ValueTask SendCharacterInformationExtendedAsync(this IConnection? connection, byte @x, byte @y, ushort @mapId, ulong @currentExperience, ulong @experienceForNextLevel, ushort @levelUpPoints, ushort @strength, ushort @agility, ushort @vitality, ushort @energy, ushort @leadership, uint @currentHealth, uint @maximumHealth, uint @currentMana, uint @maximumMana, uint @currentShield, uint @maximumShield, uint @currentAbility, uint @maximumAbility, uint @money, CharacterHeroState @heroState, CharacterStatus @status, ushort @usedFruitPoints, ushort @maxFruitPoints, ushort @usedNegativeFruitPoints, ushort @maxNegativeFruitPoints, ushort @attackSpeed, ushort @magicSpeed, ushort @maximumAttackSpeed, byte @inventoryExtensions, ushort @resets) { if (connection is null) { @@ -3430,6 +3431,7 @@ int WritePacket() packet.MagicSpeed = @magicSpeed; packet.MaximumAttackSpeed = @maximumAttackSpeed; packet.InventoryExtensions = @inventoryExtensions; + packet.Resets = @resets; return packet.Header.Length; } diff --git a/src/Network/Packets/ServerToClient/ServerToClientPackets.cs b/src/Network/Packets/ServerToClient/ServerToClientPackets.cs index 5963596c2..a179ce06d 100644 --- a/src/Network/Packets/ServerToClient/ServerToClientPackets.cs +++ b/src/Network/Packets/ServerToClient/ServerToClientPackets.cs @@ -17141,7 +17141,7 @@ private CharacterInformationExtended(Memory data, bool initialize) /// /// Gets the initial length of this data packet. When the size is dynamic, this value may be bigger than actually needed. /// - public static int Length => 96; + public static int Length => 92; /// /// Gets the header of this packet. @@ -17418,6 +17418,15 @@ public byte InventoryExtensions set => this._data.Span[88] = value; } + /// + /// Gets or sets the resets. + /// + public ushort Resets + { + get => ReadUInt16LittleEndian(this._data.Span[90..]); + set => WriteUInt16LittleEndian(this._data.Span[90..], value); + } + /// /// Performs an implicit conversion from a Memory of bytes to a . /// diff --git a/src/Network/Packets/ServerToClient/ServerToClientPackets.xml b/src/Network/Packets/ServerToClient/ServerToClientPackets.xml index 23880ef22..0da077bec 100644 --- a/src/Network/Packets/ServerToClient/ServerToClientPackets.xml +++ b/src/Network/Packets/ServerToClient/ServerToClientPackets.xml @@ -6322,7 +6322,7 @@ F3 03 CharacterInformationExtended - 96 + 92 ServerToClient After the character was selected by the player and entered the game. The characters enters the game world. @@ -6479,6 +6479,12 @@ Byte InventoryExtensions + + + 90 + ShortLittleEndian + Resets + diff --git a/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs b/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs index 34e33aa2e..a3fb53205 100644 --- a/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs +++ b/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs @@ -16289,7 +16289,7 @@ private CharacterInformationExtendedRef(Span data, bool initialize) /// /// Gets the initial length of this data packet. When the size is dynamic, this value may be bigger than actually needed. /// - public static int Length => 96; + public static int Length => 92; /// /// Gets the header of this packet. @@ -16566,6 +16566,15 @@ public byte InventoryExtensions set => this._data[88] = value; } + /// + /// Gets or sets the resets. + /// + public ushort Resets + { + get => ReadUInt16LittleEndian(this._data[90..]); + set => WriteUInt16LittleEndian(this._data[90..], value); + } + /// /// Performs an implicit conversion from a Span of bytes to a . /// diff --git a/tests/MUnique.OpenMU.Network.Packets.Tests/ServerToClientPacketTests.cs b/tests/MUnique.OpenMU.Network.Packets.Tests/ServerToClientPacketTests.cs index 07c1acdcc..a9fa18ad4 100644 --- a/tests/MUnique.OpenMU.Network.Packets.Tests/ServerToClientPacketTests.cs +++ b/tests/MUnique.OpenMU.Network.Packets.Tests/ServerToClientPacketTests.cs @@ -3423,7 +3423,7 @@ public void CharacterLevelUpdateExtended_PacketSizeValidation() public void CharacterInformationExtended_PacketSizeValidation() { // Fixed-length packet validation - const int expectedLength = 96; + const int expectedLength = 92; var actualLength = CharacterInformationExtendedRef.Length; Assert.That(actualLength, Is.EqualTo(expectedLength), @@ -3548,6 +3548,10 @@ public void CharacterInformationExtended_PacketSizeValidation() // Validate field 'InventoryExtensions' boundary Assert.That(88 + 1, Is.LessThanOrEqualTo(expectedLength), "Field 'InventoryExtensions' exceeds packet boundary"); + + // Validate field 'Resets' boundary + Assert.That(90 + 2, Is.LessThanOrEqualTo(expectedLength), + "Field 'Resets' exceeds packet boundary"); } ///