diff --git a/docs/Packets/C1-1B-MagicEffectCancelRequest_by-client.md b/docs/Packets/C1-1B-MagicEffectCancelRequest_by-client.md
index abba606..06bbf52 100644
--- a/docs/Packets/C1-1B-MagicEffectCancelRequest_by-client.md
+++ b/docs/Packets/C1-1B-MagicEffectCancelRequest_by-client.md
@@ -2,7 +2,7 @@
## Is sent when
-A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardy Enhance'.
+A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardry Enhance'.
## Causes the following actions on the server side
diff --git a/src/Network/Packets/ClientToServer/ClientToServerPackets.cs b/src/Network/Packets/ClientToServer/ClientToServerPackets.cs
index 9eaeee2..b22a6c7 100644
--- a/src/Network/Packets/ClientToServer/ClientToServerPackets.cs
+++ b/src/Network/Packets/ClientToServer/ClientToServerPackets.cs
@@ -17604,6 +17604,83 @@ public readonly struct HeykelSavasiTeamSelect
/// The packet as byte span.
public static implicit operator Memory(HeykelSavasiTeamSelect packet) => packet._data;
}
+
+
+///
+/// Is sent by the client when: A client which supports a user interface for chat commands requests the list of commands which are available to the player. It's usually sent after the character entered the game world.
+/// Causes reaction on server side: The server sends an AvailableChatCommand message for each available chat command.
+///
+public readonly struct ChatCommandListRequest
+{
+ private readonly Memory _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public ChatCommandListRequest(Memory data)
+ : this(data, true)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ /// If set to true, the header data is automatically initialized and written to the underlying span.
+ private ChatCommandListRequest(Memory data, bool initialize)
+ {
+ this._data = data;
+ if (initialize)
+ {
+ var header = this.Header;
+ header.Type = HeaderType;
+ header.Code = Code;
+ header.Length = (byte)Math.Min(data.Length, Length);
+ header.SubCode = SubCode;
+ }
+ }
+
+ ///
+ /// Gets the header type of this data packet.
+ ///
+ public static byte HeaderType => 0xC1;
+
+ ///
+ /// Gets the operation code of this data packet.
+ ///
+ public static byte Code => 0xF5;
+
+ ///
+ /// Gets the operation sub-code of this data packet.
+ /// The is used as a grouping key.
+ ///
+ public static byte SubCode => 0x00;
+
+ ///
+ /// 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 => 4;
+
+ ///
+ /// Gets the header of this packet.
+ ///
+ public C1HeaderWithSubCode Header => new (this._data);
+
+ ///
+ /// Performs an implicit conversion from a Memory of bytes to a .
+ ///
+ /// The packet as span.
+ /// The packet as struct.
+ public static implicit operator ChatCommandListRequest(Memory packet) => new (packet, false);
+
+ ///
+ /// Performs an implicit conversion from to a Memory of bytes.
+ ///
+ /// The packet as struct.
+ /// The packet as byte span.
+ public static implicit operator Memory(ChatCommandListRequest packet) => packet._data;
+}
///
/// The state of the trade button.
///
diff --git a/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs b/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs
index 94a9a49..551379d 100644
--- a/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs
+++ b/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs
@@ -17397,3 +17397,80 @@ public readonly ref struct HeykelSavasiTeamSelectRef
/// The packet as byte span.
public static implicit operator Span(HeykelSavasiTeamSelectRef packet) => packet._data;
}
+
+
+///
+/// Is sent by the client when: A client which supports a user interface for chat commands requests the list of commands which are available to the player. It's usually sent after the character entered the game world.
+/// Causes reaction on server side: The server sends an AvailableChatCommand message for each available chat command.
+///
+public readonly ref struct ChatCommandListRequestRef
+{
+ private readonly Span _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public ChatCommandListRequestRef(Span data)
+ : this(data, true)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ /// If set to true, the header data is automatically initialized and written to the underlying span.
+ private ChatCommandListRequestRef(Span data, bool initialize)
+ {
+ this._data = data;
+ if (initialize)
+ {
+ var header = this.Header;
+ header.Type = HeaderType;
+ header.Code = Code;
+ header.Length = (byte)Math.Min(data.Length, Length);
+ header.SubCode = SubCode;
+ }
+ }
+
+ ///
+ /// Gets the header type of this data packet.
+ ///
+ public static byte HeaderType => 0xC1;
+
+ ///
+ /// Gets the operation code of this data packet.
+ ///
+ public static byte Code => 0xF5;
+
+ ///
+ /// Gets the operation sub-code of this data packet.
+ /// The is used as a grouping key.
+ ///
+ public static byte SubCode => 0x00;
+
+ ///
+ /// 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 => 4;
+
+ ///
+ /// Gets the header of this packet.
+ ///
+ public C1HeaderWithSubCodeRef Header => new (this._data);
+
+ ///
+ /// Performs an implicit conversion from a Span of bytes to a .
+ ///
+ /// The packet as span.
+ /// The packet as struct.
+ public static implicit operator ChatCommandListRequestRef(Span packet) => new (packet, false);
+
+ ///
+ /// Performs an implicit conversion from to a Span of bytes.
+ ///
+ /// The packet as struct.
+ /// The packet as byte span.
+ public static implicit operator Span(ChatCommandListRequestRef packet) => packet._data;
+}
diff --git a/src/Network/Packets/ClientToServer/ConnectionExtensions.cs b/src/Network/Packets/ClientToServer/ConnectionExtensions.cs
index 6f3f0d5..5814469 100644
--- a/src/Network/Packets/ClientToServer/ConnectionExtensions.cs
+++ b/src/Network/Packets/ClientToServer/ConnectionExtensions.cs
@@ -5574,5 +5574,30 @@ public static class ConnectionExtensions
return packet.Header.Length;
}
+ await connection.SendAsync(WritePacket).ConfigureAwait(false);
+ }
+
+ ///
+ /// Sends a to this connection.
+ ///
+ /// The connection.
+ ///
+ /// Is sent by the client when: A client which supports a user interface for chat commands requests the list of commands which are available to the player. It's usually sent after the character entered the game world.
+ /// Causes reaction on server side: The server sends an AvailableChatCommand message for each available chat command.
+ ///
+ public static async ValueTask SendChatCommandListRequestAsync(this IConnection? connection)
+ {
+ if (connection is null)
+ {
+ return;
+ }
+
+ int WritePacket()
+ {
+ var length = ChatCommandListRequestRef.Length;
+ var packet = new ChatCommandListRequestRef(connection.Output.GetSpan(length)[..length]);
+ return packet.Header.Length;
+ }
+
await connection.SendAsync(WritePacket).ConfigureAwait(false);
}}
\ No newline at end of file
diff --git a/src/Network/Packets/ServerToClient/ServerToClientPackets.cs b/src/Network/Packets/ServerToClient/ServerToClientPackets.cs
index 054452e..0399bf2 100644
--- a/src/Network/Packets/ServerToClient/ServerToClientPackets.cs
+++ b/src/Network/Packets/ServerToClient/ServerToClientPackets.cs
@@ -31163,6 +31163,221 @@ public readonly struct ScoreEntry
set => WriteUInt32BigEndian(this._data.Span[13..], value);
}
}
+}
+
+
+///
+/// Is sent by the server when: After the client requested the list of available chat commands. One message is sent for each command which is available to the player.
+/// Causes reaction on client side: The client adds the command to its list of known commands, so that it can offer them to the player without requiring him to know or type them.
+///
+public readonly struct AvailableChatCommand
+{
+ private readonly Memory _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public AvailableChatCommand(Memory data)
+ : this(data, true)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ /// If set to true, the header data is automatically initialized and written to the underlying span.
+ private AvailableChatCommand(Memory data, bool initialize)
+ {
+ this._data = data;
+ if (initialize)
+ {
+ var header = this.Header;
+ header.Type = HeaderType;
+ header.Code = Code;
+ header.Length = (ushort)data.Length;
+ header.SubCode = SubCode;
+ }
+ }
+
+ ///
+ /// Gets the header type of this data packet.
+ ///
+ public static byte HeaderType => 0xC2;
+
+ ///
+ /// Gets the operation code of this data packet.
+ ///
+ public static byte Code => 0xF5;
+
+ ///
+ /// Gets the operation sub-code of this data packet.
+ /// The is used as a grouping key.
+ ///
+ public static byte SubCode => 0x01;
+
+ ///
+ /// Gets the header of this packet.
+ ///
+ public C2HeaderWithSubCode Header => new (this._data);
+
+ ///
+ /// Gets or sets the index of this command within the list, starting at 0.
+ ///
+ public byte Index
+ {
+ get => this._data.Span[5];
+ set => this._data.Span[5] = value;
+ }
+
+ ///
+ /// Gets or sets the total number of commands which are available to the player, so that the client knows when it received all of them.
+ ///
+ public byte Count
+ {
+ get => this._data.Span[6];
+ set => this._data.Span[6] = value;
+ }
+
+ ///
+ /// Gets or sets the character status which is required to execute the command.
+ ///
+ public CharacterStatus MinimumCharacterStatus
+ {
+ get => (CharacterStatus)this._data.Span[7];
+ set => this._data.Span[7] = (byte)value;
+ }
+
+ ///
+ /// Gets or sets the parameter count.
+ ///
+ public byte ParameterCount
+ {
+ get => this._data.Span[8];
+ set => this._data.Span[8] = value;
+ }
+
+ ///
+ /// Gets or sets the command including its slash, e.g. '/item'.
+ ///
+ public string Command
+ {
+ get => this._data.Span.ExtractString(9, 32, System.Text.Encoding.UTF8);
+ set => this._data.Slice(9, 32).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the name of the command, in the language of the player.
+ ///
+ public string Name
+ {
+ get => this._data.Span.ExtractString(41, 48, System.Text.Encoding.UTF8);
+ set => this._data.Slice(41, 48).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the description of the command, in the language of the player.
+ ///
+ public string Description
+ {
+ get => this._data.Span.ExtractString(89, 256, System.Text.Encoding.UTF8);
+ set => this._data.Slice(89, 256).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets the of the specified index.
+ ///
+ public ChatCommandParameter this[int index] => new (this._data.Slice(345 + index * ChatCommandParameter.Length));
+
+ ///
+ /// Performs an implicit conversion from a Memory of bytes to a .
+ ///
+ /// The packet as span.
+ /// The packet as struct.
+ public static implicit operator AvailableChatCommand(Memory packet) => new (packet, false);
+
+ ///
+ /// Performs an implicit conversion from to a Memory of bytes.
+ ///
+ /// The packet as struct.
+ /// The packet as byte span.
+ public static implicit operator Memory(AvailableChatCommand packet) => packet._data;
+
+ ///
+ /// Calculates the size of the packet for the specified count of .
+ ///
+ /// The count of from which the size will be calculated.
+
+ public static int GetRequiredSize(int parametersCount) => parametersCount * ChatCommandParameter.Length + 345;
+
+
+///
+/// Describes one parameter of a chat command, so that a user interface can offer an input for it..
+///
+public readonly struct ChatCommandParameter
+{
+ private readonly Memory _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public ChatCommandParameter(Memory data)
+ {
+ this._data = data;
+ }
+
+ ///
+ /// 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 => 102;
+
+ ///
+ /// Gets or sets defines if the parameter has to be specified to execute the command.
+ ///
+ public bool IsRequired
+ {
+ get => this._data.Span.GetBoolean();
+ set => this._data.Span.SetBoolean(value);
+ }
+
+ ///
+ /// Gets or sets the kind of value which is expected, so that a fitting input can be shown.
+ ///
+ public ChatCommandParameterType Type
+ {
+ get => (ChatCommandParameterType)this._data.Span[1];
+ set => this._data.Span[1] = (byte)value;
+ }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ public string Name
+ {
+ get => this._data.Span.ExtractString(2, 32, System.Text.Encoding.UTF8);
+ set => this._data.Slice(2, 32).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the short name which is used in the 'shortName=value' notation. It's empty when the parameter can only be passed by its position.
+ ///
+ public string ShortName
+ {
+ get => this._data.Span.ExtractString(34, 20, System.Text.Encoding.UTF8);
+ set => this._data.Slice(34, 20).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the accepted values, separated by a pipe. It's empty when the parameter isn't limited to a set of values.
+ ///
+ public string ValidValues
+ {
+ get => this._data.Span.ExtractString(54, 48, System.Text.Encoding.UTF8);
+ set => this._data.Slice(54, 48).Span.WriteString(value, System.Text.Encoding.UTF8);
+ }
+}
}
///
/// Defines the role of a guild member.
diff --git a/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs b/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs
index f054c49..ad319f8 100644
--- a/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs
+++ b/src/Network/Packets/ServerToClient/ServerToClientPacketsRef.cs
@@ -29527,3 +29527,218 @@ public readonly ref struct ScoreEntryRef
}
}
}
+
+
+///
+/// Is sent by the server when: After the client requested the list of available chat commands. One message is sent for each command which is available to the player.
+/// Causes reaction on client side: The client adds the command to its list of known commands, so that it can offer them to the player without requiring him to know or type them.
+///
+public readonly ref struct AvailableChatCommandRef
+{
+ private readonly Span _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public AvailableChatCommandRef(Span data)
+ : this(data, true)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ /// If set to true, the header data is automatically initialized and written to the underlying span.
+ private AvailableChatCommandRef(Span data, bool initialize)
+ {
+ this._data = data;
+ if (initialize)
+ {
+ var header = this.Header;
+ header.Type = HeaderType;
+ header.Code = Code;
+ header.Length = (ushort)data.Length;
+ header.SubCode = SubCode;
+ }
+ }
+
+ ///
+ /// Gets the header type of this data packet.
+ ///
+ public static byte HeaderType => 0xC2;
+
+ ///
+ /// Gets the operation code of this data packet.
+ ///
+ public static byte Code => 0xF5;
+
+ ///
+ /// Gets the operation sub-code of this data packet.
+ /// The is used as a grouping key.
+ ///
+ public static byte SubCode => 0x01;
+
+ ///
+ /// Gets the header of this packet.
+ ///
+ public C2HeaderWithSubCodeRef Header => new (this._data);
+
+ ///
+ /// Gets or sets the index of this command within the list, starting at 0.
+ ///
+ public byte Index
+ {
+ get => this._data[5];
+ set => this._data[5] = value;
+ }
+
+ ///
+ /// Gets or sets the total number of commands which are available to the player, so that the client knows when it received all of them.
+ ///
+ public byte Count
+ {
+ get => this._data[6];
+ set => this._data[6] = value;
+ }
+
+ ///
+ /// Gets or sets the character status which is required to execute the command.
+ ///
+ public CharacterStatus MinimumCharacterStatus
+ {
+ get => (CharacterStatus)this._data[7];
+ set => this._data[7] = (byte)value;
+ }
+
+ ///
+ /// Gets or sets the parameter count.
+ ///
+ public byte ParameterCount
+ {
+ get => this._data[8];
+ set => this._data[8] = value;
+ }
+
+ ///
+ /// Gets or sets the command including its slash, e.g. '/item'.
+ ///
+ public string Command
+ {
+ get => this._data.ExtractString(9, 32, System.Text.Encoding.UTF8);
+ set => this._data.Slice(9, 32).WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the name of the command, in the language of the player.
+ ///
+ public string Name
+ {
+ get => this._data.ExtractString(41, 48, System.Text.Encoding.UTF8);
+ set => this._data.Slice(41, 48).WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the description of the command, in the language of the player.
+ ///
+ public string Description
+ {
+ get => this._data.ExtractString(89, 256, System.Text.Encoding.UTF8);
+ set => this._data.Slice(89, 256).WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets the of the specified index.
+ ///
+ public ChatCommandParameterRef this[int index] => new (this._data[(345 + index * ChatCommandParameterRef.Length)..]);
+
+ ///
+ /// Performs an implicit conversion from a Span of bytes to a .
+ ///
+ /// The packet as span.
+ /// The packet as struct.
+ public static implicit operator AvailableChatCommandRef(Span packet) => new (packet, false);
+
+ ///
+ /// Performs an implicit conversion from to a Span of bytes.
+ ///
+ /// The packet as struct.
+ /// The packet as byte span.
+ public static implicit operator Span(AvailableChatCommandRef packet) => packet._data;
+
+ ///
+ /// Calculates the size of the packet for the specified count of .
+ ///
+ /// The count of from which the size will be calculated.
+
+ public static int GetRequiredSize(int parametersCount) => parametersCount * ChatCommandParameterRef.Length + 345;
+
+
+///
+/// Describes one parameter of a chat command, so that a user interface can offer an input for it..
+///
+public readonly ref struct ChatCommandParameterRef
+{
+ private readonly Span _data;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The underlying data.
+ public ChatCommandParameterRef(Span data)
+ {
+ this._data = data;
+ }
+
+ ///
+ /// 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 => 102;
+
+ ///
+ /// Gets or sets defines if the parameter has to be specified to execute the command.
+ ///
+ public bool IsRequired
+ {
+ get => this._data.GetBoolean();
+ set => this._data.SetBoolean(value);
+ }
+
+ ///
+ /// Gets or sets the kind of value which is expected, so that a fitting input can be shown.
+ ///
+ public ChatCommandParameterType Type
+ {
+ get => (ChatCommandParameterType)this._data[1];
+ set => this._data[1] = (byte)value;
+ }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ public string Name
+ {
+ get => this._data.ExtractString(2, 32, System.Text.Encoding.UTF8);
+ set => this._data.Slice(2, 32).WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the short name which is used in the 'shortName=value' notation. It's empty when the parameter can only be passed by its position.
+ ///
+ public string ShortName
+ {
+ get => this._data.ExtractString(34, 20, System.Text.Encoding.UTF8);
+ set => this._data.Slice(34, 20).WriteString(value, System.Text.Encoding.UTF8);
+ }
+
+ ///
+ /// Gets or sets the accepted values, separated by a pipe. It's empty when the parameter isn't limited to a set of values.
+ ///
+ public string ValidValues
+ {
+ get => this._data.ExtractString(54, 48, System.Text.Encoding.UTF8);
+ set => this._data.Slice(54, 48).WriteString(value, System.Text.Encoding.UTF8);
+ }
+}
+}