Merge branch 'MCCTeam:master' into master

This commit is contained in:
harry 2026-06-20 13:53:07 +01:00 committed by GitHub
commit 37f71d4494
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
639 changed files with 126385 additions and 17202 deletions

View file

@ -21,13 +21,13 @@ namespace MinecraftClient.Protocol
/// <returns></returns>
private static Dictionary<int, string> LoadRegistry(string registriesJsonFile, string jsonRegistryName)
{
Json.JSONData rawJson = Json.ParseJson(File.ReadAllText(registriesJsonFile));
Json.JSONData rawRegistry = rawJson.Properties[jsonRegistryName].Properties["entries"];
var rawJson = Json.ParseJson(File.ReadAllText(registriesJsonFile));
var rawRegistry = rawJson![jsonRegistryName]!["entries"]!.AsObject();
Dictionary<int, string> registry = new();
foreach (KeyValuePair<string, Json.JSONData> entry in rawRegistry.Properties)
foreach (var entry in rawRegistry)
{
int entryId = int.Parse(entry.Value.Properties["protocol_id"].StringValue, NumberStyles.Any, CultureInfo.CurrentCulture);
int entryId = int.Parse(entry.Value!["protocol_id"].GetStringValue(), NumberStyles.Any, CultureInfo.CurrentCulture);
//minecraft:item_name => ItemName
string entryName = String.Concat(

View file

@ -0,0 +1,475 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MinecraftClient.Dialogs;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Dialogs;
public sealed class DialogNbtParser
{
public DialogDefinition Parse(Dictionary<string, object> nbt)
{
var type = NormalizeType(GetString(nbt, "type") ?? "minecraft:notice");
var common = ParseCommon(nbt, type);
var actions = new List<DialogButton>();
DialogActionDefinition? cancelAction = null;
var columns = GetInt(nbt, "columns", 1);
var buttonWidth = GetInt(nbt, "button_width", 150);
switch (type)
{
case "minecraft:notice":
var noticeAction = ParseButton(nbt, "action", 1);
actions.Add(noticeAction ?? new DialogButton(1, Translations.dialog_action_ok, null));
cancelAction = actions[0].Action;
break;
case "minecraft:confirmation":
AddIfNotNull(actions, ParseButton(nbt, "yes", 1));
AddIfNotNull(actions, ParseButton(nbt, "no", 2));
cancelAction = actions.Count >= 2 ? actions[1].Action : null;
break;
case "minecraft:multi_action":
actions.AddRange(ParseButtonList(GetValue(nbt, "actions")));
cancelAction = ParseButton(nbt, "exit_action", 0)?.Action;
break;
case "minecraft:dialog_list":
actions.AddRange(ParseDialogListActions(GetValue(nbt, "dialogs")));
cancelAction = ParseButton(nbt, "exit_action", 0)?.Action;
break;
case "minecraft:server_links":
cancelAction = ParseButton(nbt, "exit_action", 0)?.Action;
break;
}
return new DialogDefinition(
type,
common.Title,
common.ExternalTitle,
common.CanCloseWithEscape,
common.Pause,
common.AfterAction,
common.Body,
common.Inputs,
actions,
cancelAction,
columns,
buttonWidth);
}
public DialogDefinition? TryParse(Dictionary<string, object>? nbt)
{
return nbt is null ? null : Parse(nbt);
}
private static DialogCommon ParseCommon(Dictionary<string, object> nbt, string type)
{
var title = ParseComponent(GetValue(nbt, "title"));
var externalTitle = nbt.TryGetValue("external_title", out var externalTitleValue)
? ParseComponent(externalTitleValue)
: null;
var canCloseWithEscape = GetBool(nbt, "can_close_with_escape", true);
var pause = GetBool(nbt, "pause", true);
var afterAction = ParseAfterAction(GetString(nbt, "after_action") ?? "close");
var body = ParseBody(GetValue(nbt, "body"));
var inputs = ParseInputs(GetValue(nbt, "inputs"));
return new DialogCommon(title, externalTitle, canCloseWithEscape, pause, afterAction, body, inputs);
}
private static IReadOnlyList<DialogBody> ParseBody(object? value)
{
if (value is null)
return [];
List<DialogBody> body = [];
foreach (var item in Enumerate(value))
{
if (item is Dictionary<string, object> compound)
{
var type = NormalizeType(GetString(compound, "type") ?? "minecraft:plain_message");
if (type == "minecraft:item")
{
var description = compound.TryGetValue("description", out var desc)
? ParsePlainMessage(desc)
: string.Empty;
body.Add(new DialogBody(DialogBodyKind.Item, string.IsNullOrWhiteSpace(description) ? Translations.dialog_item_body : description, type));
continue;
}
body.Add(new DialogBody(DialogBodyKind.PlainMessage, ParsePlainMessage(compound), type));
continue;
}
body.Add(new DialogBody(DialogBodyKind.PlainMessage, ParseComponent(item), "minecraft:plain_message"));
}
return body;
}
private static string ParsePlainMessage(object? value)
{
if (value is Dictionary<string, object> compound && compound.TryGetValue("contents", out var contents))
return ParseComponent(contents);
return ParseComponent(value);
}
private static IReadOnlyList<DialogInput> ParseInputs(object? value)
{
if (value is null)
return [];
List<DialogInput> inputs = [];
foreach (var item in Enumerate(value))
{
if (item is not Dictionary<string, object> inputData)
continue;
var key = GetString(inputData, "key");
if (string.IsNullOrWhiteSpace(key))
continue;
var control = inputData.TryGetValue("control", out var controlValue) && controlValue is Dictionary<string, object> controlData
? controlData
: inputData;
var type = NormalizeType(GetString(control, "type") ?? "minecraft:text");
inputs.Add(type switch
{
"minecraft:boolean" => ParseBooleanInput(key, type, control),
"minecraft:number_range" => ParseNumberInput(key, type, control),
"minecraft:single_option" => ParseOptionInput(key, type, control),
"minecraft:text" => ParseTextInput(key, type, control),
_ => new DialogInput(key, DialogInputKind.Unknown, ParseComponent(GetValue(control, "label")), string.Empty, Type: type)
});
}
return inputs;
}
private static DialogInput ParseTextInput(string key, string type, Dictionary<string, object> control)
{
return new DialogInput(
key,
DialogInputKind.Text,
ParseComponent(GetValue(control, "label")),
GetString(control, "initial") ?? string.Empty,
MaxLength: GetInt(control, "max_length", 32),
LabelVisible: GetBool(control, "label_visible", true),
Multiline: control.ContainsKey("multiline"),
Type: type);
}
private static DialogInput ParseBooleanInput(string key, string type, Dictionary<string, object> control)
{
var initial = GetBool(control, "initial", false);
return new DialogInput(
key,
DialogInputKind.Boolean,
ParseComponent(GetValue(control, "label")),
initial ? "true" : "false",
OnTrue: GetString(control, "on_true") ?? "true",
OnFalse: GetString(control, "on_false") ?? "false",
Type: type);
}
private static DialogInput ParseOptionInput(string key, string type, Dictionary<string, object> control)
{
var options = ParseOptions(GetValue(control, "options"));
var initial = options.FirstOrDefault(static option => option.Initial)?.Id
?? options.FirstOrDefault()?.Id
?? string.Empty;
return new DialogInput(
key,
DialogInputKind.SingleOption,
ParseComponent(GetValue(control, "label")),
initial,
LabelVisible: GetBool(control, "label_visible", true),
Options: options,
Type: type);
}
private static DialogInput ParseNumberInput(string key, string type, Dictionary<string, object> control)
{
var range = control.TryGetValue("range_info", out var rangeValue) && rangeValue is Dictionary<string, object> rangeData
? rangeData
: control;
var start = GetFloat(range, "start", 0);
var end = GetFloat(range, "end", 1);
var initial = TryGetFloat(range, "initial") ?? ((start + end) / 2F);
return new DialogInput(
key,
DialogInputKind.NumberRange,
ParseComponent(GetValue(control, "label")),
NumberToString(initial),
Start: start,
End: end,
InitialNumber: initial,
Step: TryGetFloat(range, "step"),
Type: type);
}
private static IReadOnlyList<DialogOption> ParseOptions(object? value)
{
if (value is null)
return [];
List<DialogOption> options = [];
foreach (var item in Enumerate(value))
{
if (item is string id)
{
options.Add(new DialogOption(id, id, false));
continue;
}
if (item is Dictionary<string, object> option)
{
var optionId = GetString(option, "id");
if (optionId is null)
continue;
var display = option.TryGetValue("display", out var displayValue)
? ParseComponent(displayValue)
: optionId;
options.Add(new DialogOption(optionId, display, GetBool(option, "initial", false)));
}
}
return options;
}
private static List<DialogButton> ParseButtonList(object? value)
{
List<DialogButton> buttons = [];
var index = 1;
foreach (var item in Enumerate(value))
{
if (item is Dictionary<string, object> buttonData)
buttons.Add(ParseButton(buttonData, index++) ?? new DialogButton(index - 1, Translations.dialog_action_unnamed, null));
}
return buttons;
}
private static IEnumerable<DialogButton> ParseDialogListActions(object? value)
{
List<DialogButton> buttons = [];
var index = 1;
foreach (var item in Enumerate(value))
{
switch (item)
{
case string tag when tag.StartsWith('#'):
buttons.Add(new DialogButton(index++, tag, new DialogActionDefinition(DialogActionKind.Unknown, Type: "dialog_tag")));
break;
case string resource:
buttons.Add(new DialogButton(index++, resource, new DialogActionDefinition(DialogActionKind.ShowDialog, Value: resource, Type: "dialog_reference_name")));
break;
case Dictionary<string, object> dialog:
var nested = new DialogNbtParser().Parse(dialog);
buttons.Add(new DialogButton(index++, nested.DisplayTitle(), new DialogActionDefinition(DialogActionKind.ShowDialog, NestedDialog: nested)));
break;
}
}
return buttons;
}
private static DialogButton? ParseButton(Dictionary<string, object> owner, string key, int index)
{
return owner.TryGetValue(key, out var value) && value is Dictionary<string, object> data
? ParseButton(data, index)
: null;
}
private static DialogButton? ParseButton(Dictionary<string, object> data, int index)
{
var label = data.TryGetValue("label", out var labelValue)
? ParseComponent(labelValue)
: Translations.dialog_action_unnamed;
var action = data.TryGetValue("action", out var actionValue) && actionValue is Dictionary<string, object> actionData
? ParseAction(actionData)
: null;
return new DialogButton(index, label, action);
}
private static DialogActionDefinition ParseAction(Dictionary<string, object> action)
{
var type = NormalizeType(GetString(action, "type") ?? GetString(action, "action") ?? "minecraft:none");
return type switch
{
"minecraft:run_command" => new DialogActionDefinition(DialogActionKind.RunCommand, Value: GetString(action, "command"), Type: type),
"minecraft:dynamic/run_command" => new DialogActionDefinition(DialogActionKind.RunCommand, Value: GetString(action, "template"), Type: type),
"minecraft:custom" => new DialogActionDefinition(DialogActionKind.CustomClick, Id: GetString(action, "id"), Payload: GetCompound(action, "payload"), Type: type),
"minecraft:dynamic/custom" => new DialogActionDefinition(DialogActionKind.CustomClick, Id: GetString(action, "id"), Payload: GetCompound(action, "additions"), Type: type),
"minecraft:open_url" => new DialogActionDefinition(DialogActionKind.OpenUrl, Value: GetString(action, "url"), Type: type),
"minecraft:suggest_command" => new DialogActionDefinition(DialogActionKind.SuggestCommand, Value: GetString(action, "command"), Type: type),
"minecraft:copy_to_clipboard" => new DialogActionDefinition(DialogActionKind.CopyToClipboard, Value: GetString(action, "value"), Type: type),
"minecraft:show_dialog" => ParseShowDialogAction(action, type),
_ => new DialogActionDefinition(DialogActionKind.Unknown, Type: type)
};
}
private static DialogActionDefinition ParseShowDialogAction(Dictionary<string, object> action, string type)
{
if (!action.TryGetValue("dialog", out var value))
return new DialogActionDefinition(DialogActionKind.ShowDialog, Type: type);
if (value is Dictionary<string, object> dialogData)
return new DialogActionDefinition(DialogActionKind.ShowDialog, NestedDialog: new DialogNbtParser().Parse(dialogData), Type: type);
if (value is int protocolId)
return new DialogActionDefinition(DialogActionKind.ShowDialog, DialogReferenceId: protocolId, Type: type);
return new DialogActionDefinition(DialogActionKind.ShowDialog, Value: value.ToString(), Type: type);
}
private static DialogAfterAction ParseAfterAction(string value)
{
return value switch
{
"none" => DialogAfterAction.None,
"wait_for_response" => DialogAfterAction.WaitForResponse,
_ => DialogAfterAction.Close
};
}
private static string ParseComponent(object? value)
{
if (value is null)
return string.Empty;
try
{
return value switch
{
Dictionary<string, object> compound => ChatParser.ParseText(compound),
string text when text.StartsWith('{') || text.StartsWith('[') => ChatParser.ParseText(text),
string text => text,
_ => value.ToString() ?? string.Empty
};
}
catch
{
return value.ToString() ?? string.Empty;
}
}
private static IEnumerable<object> Enumerate(object? value)
{
if (value is null)
yield break;
if (value is object[] array)
{
foreach (var item in array)
yield return item;
yield break;
}
yield return value;
}
private static object? GetValue(Dictionary<string, object> data, string key)
{
return data.TryGetValue(key, out var value) ? value : null;
}
private static string? GetString(Dictionary<string, object> data, string key)
{
return data.TryGetValue(key, out var value) ? value as string ?? value.ToString() : null;
}
private static Dictionary<string, object>? GetCompound(Dictionary<string, object> data, string key)
{
return data.TryGetValue(key, out var value) && value is Dictionary<string, object> compound ? compound : null;
}
private static bool GetBool(Dictionary<string, object> data, string key, bool fallback)
{
if (!data.TryGetValue(key, out var value))
return fallback;
return value switch
{
bool boolean => boolean,
byte number => number != 0,
sbyte number => number != 0,
int number => number != 0,
string text when bool.TryParse(text, out var parsed) => parsed,
_ => fallback
};
}
private static int GetInt(Dictionary<string, object> data, string key, int fallback)
{
if (!data.TryGetValue(key, out var value))
return fallback;
return value switch
{
byte number => number,
short number => number,
int number => number,
long number => (int)number,
string text when int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) => parsed,
_ => fallback
};
}
private static float GetFloat(Dictionary<string, object> data, string key, float fallback)
{
return TryGetFloat(data, key) ?? fallback;
}
private static float? TryGetFloat(Dictionary<string, object> data, string key)
{
if (!data.TryGetValue(key, out var value))
return null;
return value switch
{
float number => number,
double number => (float)number,
int number => number,
long number => number,
string text when float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed) => parsed,
_ => null
};
}
private static string NormalizeType(string type)
{
return type.Contains(':', StringComparison.Ordinal) ? type : "minecraft:" + type;
}
private static void AddIfNotNull(List<DialogButton> buttons, DialogButton? button)
{
if (button is not null)
buttons.Add(button);
}
private static string NumberToString(float value)
{
var integer = (int)value;
return integer == value
? integer.ToString(CultureInfo.InvariantCulture)
: value.ToString(CultureInfo.InvariantCulture);
}
private sealed record DialogCommon(
string Title,
string? ExternalTitle,
bool CanCloseWithEscape,
bool Pause,
DialogAfterAction AfterAction,
IReadOnlyList<DialogBody> Body,
IReadOnlyList<DialogInput> Inputs);
}

View file

@ -2,16 +2,26 @@ namespace MinecraftClient.Protocol.Handlers;
public enum ConfigurationPacketTypesIn
{
PluginMessage,
CookieRequest,
CustomReportDetails,
Disconnect,
FeatureFlags,
FinishConfiguration,
KeepAlive,
KnownDataPacks,
Ping,
PluginMessage,
RegistryData,
ResourcePack,
RemoveResourcePack,
FeatureFlags,
ResetChat,
ResourcePack,
ServerLinks,
StoreCookie,
Transfer,
UpdateTags,
ClearDialog, // Added in 1.21.6
ShowDialog, // Added in 1.21.6
CodeOfConduct, // Added in 1.21.9
Unknown
}
}

View file

@ -8,6 +8,10 @@ public enum ConfigurationPacketTypesOut
KeepAlive,
Pong,
ResourcePackResponse,
CookieResponse,
KnownDataPacks,
CustomClickAction, // Added in 1.21.6
AcceptCodeOfConduct, // Added in 1.21.9
Unknown
}

File diff suppressed because it is too large Load diff

View file

@ -11,17 +11,8 @@ namespace MinecraftClient.Protocol.Handlers.Forge
/// <summary>
/// Represents an individual forge mod.
/// </summary>
public class ForgeMod
public record ForgeMod(string ModID, string Version)
{
public ForgeMod(String ModID, String Version)
{
this.ModID = ModID;
this.Version = Version;
}
public readonly String ModID;
public readonly String Version;
public override string ToString()
{
return ModID + " v" + Version;
@ -63,7 +54,7 @@ namespace MinecraftClient.Protocol.Handlers.Forge
/// </summary>
/// <param name="data">The modinfo JSON tag.</param>
/// <param name="fmlVersion">Forge protocol version</param>
internal ForgeInfo(Json.JSONData data, FMLVersion fmlVersion)
internal ForgeInfo(System.Text.Json.Nodes.JsonObject data, FMLVersion fmlVersion)
{
Mods = new List<ForgeMod>();
Version = fmlVersion;
@ -91,10 +82,10 @@ namespace MinecraftClient.Protocol.Handlers.Forge
// }]
// }
foreach (Json.JSONData mod in data.Properties["modList"].DataArray)
foreach (var mod in data["modList"]!.AsArray())
{
String modid = mod.Properties["modid"].StringValue;
String modversion = mod.Properties["version"].StringValue;
String modid = mod!["modid"]!.GetStringValue();
String modversion = mod["version"]!.GetStringValue();
Mods.Add(new ForgeMod(modid, modversion));
}
@ -131,10 +122,10 @@ namespace MinecraftClient.Protocol.Handlers.Forge
// "fmlNetworkVersion": 2
// }
foreach (Json.JSONData mod in data.Properties["mods"].DataArray)
foreach (var mod in data["mods"]!.AsArray())
{
String modid = mod.Properties["modId"].StringValue;
String modmarker = mod.Properties["modmarker"].StringValue;
String modid = mod!["modId"]!.GetStringValue();
String modmarker = mod["modmarker"]!.GetStringValue();
Mods.Add(new ForgeMod(modid, modmarker));
}
@ -142,7 +133,7 @@ namespace MinecraftClient.Protocol.Handlers.Forge
break;
case FMLVersion.FML3:
// Example ModInfo for Minecraft 1.18 and greater (FML3)
// "forgeData": {
// "channels": [],
// "mods": [],
@ -157,7 +148,7 @@ namespace MinecraftClient.Protocol.Handlers.Forge
// - Here is the discussion:
// see https://github.com/MinecraftForge/MinecraftForge/pull/8169
string encodedData = data.Properties["d"].StringValue;
string encodedData = data["d"]!.GetStringValue();
Queue<byte> dataPackage = decodeOptimized(encodedData);
DataTypes dataTypes = new DataTypes(Protocol18Handler.MC_1_18_1_Version);
@ -178,24 +169,26 @@ namespace MinecraftClient.Protocol.Handlers.Forge
// [ Channel Version ][ String ]
// [ Required On Client ][ Bool ]
for (var i = 0; i < modsSize; i++) {
for (var i = 0; i < modsSize; i++)
{
var channelSizeAndVersionFlag = dataTypes.ReadNextVarInt(dataPackage);
var channelSize = channelSizeAndVersionFlag >> 1;
int VERSION_FLAG_IGNORESERVERONLY = 0b1;
var isIgnoreServerOnly = (channelSizeAndVersionFlag & VERSION_FLAG_IGNORESERVERONLY) != 0;
var modId = dataTypes.ReadNextString(dataPackage);
string IGNORESERVERONLY = "IGNORED";
var modVersion = isIgnoreServerOnly ? IGNORESERVERONLY : dataTypes.ReadNextString(dataPackage);
for (var i1 = 0; i1 < channelSize; i1++) {
for (var i1 = 0; i1 < channelSize; i1++)
{
dataTypes.ReadNextString(dataPackage); // channelName
dataTypes.ReadNextString(dataPackage); // channelVersion
dataTypes.ReadNextBool(dataPackage); // requiredOnClient
}
mods.Add(modId, modVersion);
Mods.Add(new ForgeMod(modId, modVersion));
}
@ -222,7 +215,8 @@ namespace MinecraftClient.Protocol.Handlers.Forge
/// The code below is converted from forge source code, see:
/// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L361
/// </para>
private static Queue<byte> decodeOptimized(string encodedData) {
private static Queue<byte> decodeOptimized(string encodedData)
{
int size0 = encodedData[0];
int size1 = encodedData[1];
int size = size0 | (size1 << 15);

File diff suppressed because it is too large Load diff

View file

@ -118,9 +118,9 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation)
{ 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag)
{ 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficutly)
{ 0x03, PacketTypesOut.MessageAcknowledgment }, //
{ 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19
{ 0x05, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat)
{ 0x03, PacketTypesOut.ChatCommand }, // Added in 1.19
{ 0x04, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat)
{ 0x05, PacketTypesOut.ChatPreview }, // Added in 1.19 (Wiki name: Chat Preview (serverbound))
{ 0x06, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command)
{ 0x07, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information)
{ 0x08, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request)
@ -147,25 +147,24 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ 0x1D, PacketTypesOut.EntityAction }, // (Wiki name: Player Command)
{ 0x1E, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input)
{ 0x1F, PacketTypesOut.Pong }, // (Wiki name: Pong (play))
{ 0x20, PacketTypesOut.PlayerSession }, // Added in 1.19.3
{ 0x21, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings)
{ 0x22, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe)
{ 0x23, PacketTypesOut.NameItem }, // (Wiki name: Rename Item)
{ 0x24, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound))
{ 0x25, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements)
{ 0x26, PacketTypesOut.SelectTrade }, //
{ 0x27, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (Added a "Secondary Effect Present" and "Secondary Effect" fields) (Wiki name: Set Beacon) - (No need to be implemented)
{ 0x28, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound))
{ 0x29, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Set Command Block)
{ 0x2A, PacketTypesOut.UpdateCommandBlockMinecart }, //
{ 0x2B, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot)
{ 0x2C, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Set Jigsaw Block)
{ 0x2D, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Set Structure Block)
{ 0x2E, PacketTypesOut.UpdateSign }, // (Wiki name: Sign Update)
{ 0x2F, PacketTypesOut.Animation }, // (Wiki name: Swing)
{ 0x30, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity)
{ 0x31, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On)
{ 0x32, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
{ 0x20, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings)
{ 0x21, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe)
{ 0x22, PacketTypesOut.NameItem }, // (Wiki name: Rename Item)
{ 0x23, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound))
{ 0x24, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements)
{ 0x25, PacketTypesOut.SelectTrade }, //
{ 0x26, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (Added a "Secondary Effect Present" and "Secondary Effect" fields) (Wiki name: Set Beacon) - (No need to be implemented)
{ 0x27, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound))
{ 0x28, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Set Command Block)
{ 0x29, PacketTypesOut.UpdateCommandBlockMinecart }, //
{ 0x2A, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot)
{ 0x2B, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Set Jigsaw Block)
{ 0x2C, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Set Structure Block)
{ 0x2D, PacketTypesOut.UpdateSign }, // (Wiki name: Sign Update)
{ 0x2E, PacketTypesOut.Animation }, // (Wiki name: Swing)
{ 0x2F, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity)
{ 0x30, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On)
{ 0x31, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;

View file

@ -178,7 +178,7 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ 0x34, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On)
{ 0x35, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.PluginMessage },
@ -201,7 +201,7 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ 0x04, ConfigurationPacketTypesOut.Pong },
{ 0x05, ConfigurationPacketTypesOut.ResourcePackResponse }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;

View file

@ -3,8 +3,8 @@ using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1204 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Added in 1.19.4
{ 0x01, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity)
@ -125,7 +125,7 @@ public class PacketPalette1204 : PacketTypePalette
{ 0x74, PacketTypesIn.Tags }, // (Wiki name: Update Tags)
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation)
{ 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag)
@ -184,7 +184,7 @@ public class PacketPalette1204 : PacketTypePalette
{ 0x36, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.PluginMessage },
{ 0x01, ConfigurationPacketTypesIn.Disconnect },
@ -198,7 +198,7 @@ public class PacketPalette1204 : PacketTypePalette
{ 0x09, ConfigurationPacketTypesIn.UpdateTags },
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.PluginMessage },
@ -207,9 +207,9 @@ public class PacketPalette1204 : PacketTypePalette
{ 0x04, ConfigurationPacketTypesOut.Pong },
{ 0x05, ConfigurationPacketTypesOut.ResourcePackResponse }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,230 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1206 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Added in 1.19.4
{ 0x01, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity)
{ 0x02, PacketTypesIn.SpawnExperienceOrb }, // (Wiki name: Spawn Exeprience Orb)
{ 0x03, PacketTypesIn.EntityAnimation }, // (Wiki name: Entity Animation (clientbound))
{ 0x04, PacketTypesIn.Statistics }, // (Wiki name: Award Statistics)
{ 0x05, PacketTypesIn.BlockChangedAck }, // Added 1.19 (Wiki name: Acknowledge Block Change)
{ 0x06, PacketTypesIn.BlockBreakAnimation }, // (Wiki name: Set Block Destroy Stage)
{ 0x07, PacketTypesIn.BlockEntityData }, //
{ 0x08, PacketTypesIn.BlockAction }, //
{ 0x09, PacketTypesIn.BlockChange }, // (Wiki name: Block Update)
{ 0x0A, PacketTypesIn.BossBar }, //
{ 0x0B, PacketTypesIn.ServerDifficulty }, // (Wiki name: Change Difficulty)
{ 0x0C, PacketTypesIn.ChunkBatchFinished }, // Added in 1.20.2
{ 0x0D, PacketTypesIn.ChunkBatchStarted }, // Added in 1.20.2
{ 0x0E, PacketTypesIn.ChunksBiomes }, // Added in 1.19.4
{ 0x0F, PacketTypesIn.ClearTiles }, //
{ 0x10, PacketTypesIn.TabComplete }, // (Wiki name: Command Suggestions Response)
{ 0x11, PacketTypesIn.DeclareCommands }, // (Wiki name: Commands)
{ 0x12, PacketTypesIn.CloseWindow }, // (Wiki name: Close Container (clientbound))
{ 0x13, PacketTypesIn.WindowItems }, // (Wiki name: Set Container Content)
{ 0x14, PacketTypesIn.WindowProperty }, // (Wiki name: Set Container Property)
{ 0x15, PacketTypesIn.SetSlot }, // (Wiki name: Set Container Slot)
{ 0x16, PacketTypesIn.CookieRequest }, // Added in 1.20.6
{ 0x17, PacketTypesIn.SetCooldown }, //
{ 0x18, PacketTypesIn.ChatSuggestions }, // Added in 1.19.1
{ 0x19, PacketTypesIn.PluginMessage }, // (Wiki name: Plugin Message (clientbound))
{ 0x1A, PacketTypesIn.DamageEvent }, // Added in 1.19.4
{ 0x1B, PacketTypesIn.DebugSample }, // Added in 1.20.6
{ 0x1C, PacketTypesIn.HideMessage }, // Added in 1.19.1
{ 0x1D, PacketTypesIn.Disconnect }, //
{ 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Added in 1.19.3 (Wiki name: Disguised Chat Message)
{ 0x1F, PacketTypesIn.EntityStatus }, // (Wiki name: Entity Event)
{ 0x20, PacketTypesIn.Explosion }, // Changed in 1.19 (Location fields are now Double instead of Float) (Wiki name: Explosion)
{ 0x21, PacketTypesIn.UnloadChunk }, // (Wiki name: Forget Chunk)
{ 0x22, PacketTypesIn.ChangeGameState }, // (Wiki name: Game Event)
{ 0x23, PacketTypesIn.OpenHorseWindow }, // (Wiki name: Horse Screen Open)
{ 0x24, PacketTypesIn.HurtAnimation }, // Added in 1.19.4
{ 0x25, PacketTypesIn.InitializeWorldBorder }, //
{ 0x26, PacketTypesIn.KeepAlive }, //
{ 0x27, PacketTypesIn.ChunkData }, //
{ 0x28, PacketTypesIn.Effect }, // (Wiki name: World Event)
{ 0x29, PacketTypesIn.Particle }, // Changed in 1.19 (Wiki name: Level Particle) (No need to be implemented)
{ 0x2A, PacketTypesIn.UpdateLight }, // (Wiki name: Light Update)
{ 0x2B, PacketTypesIn.JoinGame }, // Changed in 1.20.2 (Wiki name: Login (play))
{ 0x2C, PacketTypesIn.MapData }, // (Wiki name: Map Item Data)
{ 0x2D, PacketTypesIn.TradeList }, // (Wiki name: Merchant Offers)
{ 0x2E, PacketTypesIn.EntityPosition }, // (Wiki name: Move Entity Position)
{ 0x2F, PacketTypesIn.EntityPositionAndRotation }, // (Wiki name: Move Entity Position and Rotation)
{ 0x30, PacketTypesIn.EntityRotation }, // (Wiki name: Move Entity Rotation)
{ 0x31, PacketTypesIn.VehicleMove }, // (Wiki name: Move Vehicle)
{ 0x32, PacketTypesIn.OpenBook }, //
{ 0x33, PacketTypesIn.OpenWindow }, // (Wiki name: Open Screen)
{ 0x34, PacketTypesIn.OpenSignEditor }, //
{ 0x35, PacketTypesIn.Ping }, // (Wiki name: Ping (play))
{ 0x36, PacketTypesIn.PingResponse }, // Added in 1.20.2
{ 0x37, PacketTypesIn.CraftRecipeResponse }, // (Wiki name: Place Ghost Recipe)
{ 0x38, PacketTypesIn.PlayerAbilities }, //
{ 0x39, PacketTypesIn.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Player Chat Message)
{ 0x3A, PacketTypesIn.EndCombatEvent }, // (Wiki name: End Combat)
{ 0x3B, PacketTypesIn.EnterCombatEvent }, // (Wiki name: Enter Combat)
{ 0x3C, PacketTypesIn.DeathCombatEvent }, // (Wiki name: Combat Death)
{ 0x3D, PacketTypesIn.PlayerRemove }, // Added in 1.19.3 (Not used)
{ 0x3E, PacketTypesIn.PlayerInfo }, // Changed in 1.19 (Heavy changes)
{ 0x3F, PacketTypesIn.FacePlayer }, // (Wiki name: Player Look At)
{ 0x40, PacketTypesIn.PlayerPositionAndLook }, // (Wiki name: Synchronize Player Position)
{ 0x41, PacketTypesIn.UnlockRecipes }, // (Wiki name: Update Recipe Book)
{ 0x42, PacketTypesIn.DestroyEntities }, // (Wiki name: Remove Entites)
{ 0x43, PacketTypesIn.RemoveEntityEffect }, //
{ 0x44, PacketTypesIn.ResetScore }, // Added in 1.20.3
{ 0x45, PacketTypesIn.RemoveResourcePack }, // Added in 1.20.3
{ 0x46, PacketTypesIn.ResourcePackSend }, // (Wiki name: Add Resource pack (play))
{ 0x47, PacketTypesIn.Respawn }, // Changed in 1.20.2
{ 0x48, PacketTypesIn.EntityHeadLook }, // (Wiki name: Set Head Rotation)
{ 0x49, PacketTypesIn.MultiBlockChange }, // (Wiki name: Update Section Blocks)
{ 0x4A, PacketTypesIn.SelectAdvancementTab }, //
{ 0x4B, PacketTypesIn.ServerData }, // Added in 1.19
{ 0x4C, PacketTypesIn.ActionBar }, // (Wiki name: Set Action Bar Text)
{ 0x4D, PacketTypesIn.WorldBorderCenter }, // (Wiki name: Set Border Center)
{ 0x4E, PacketTypesIn.WorldBorderLerpSize }, //
{ 0x4F, PacketTypesIn.WorldBorderSize }, // (Wiki name: Set World Border Size)
{ 0x50, PacketTypesIn.WorldBorderWarningDelay }, // (Wiki name: Set World Border Warning Delay)
{ 0x51, PacketTypesIn.WorldBorderWarningReach }, // (Wiki name: Set Border Warning Distance)
{ 0x52, PacketTypesIn.Camera }, // (Wiki name: Set Camera)
{ 0x53, PacketTypesIn.HeldItemChange }, // (Wiki name: Set Held Item)
{ 0x54, PacketTypesIn.UpdateViewPosition }, // (Wiki name: Set Center Chunk)
{ 0x55, PacketTypesIn.UpdateViewDistance }, // (Wiki name: Set Render Distance)
{ 0x56, PacketTypesIn.SpawnPosition }, // (Wiki name: Set Default Spawn Position)
{ 0x57, PacketTypesIn.DisplayScoreboard }, // (Wiki name: Set Display Objective)
{ 0x58, PacketTypesIn.EntityMetadata }, // (Wiki name: Set Entity Metadata)
{ 0x59, PacketTypesIn.AttachEntity }, // (Wiki name: Link Entities)
{ 0x5A, PacketTypesIn.EntityVelocity }, // (Wiki name: Set Entity Velocity)
{ 0x5B, PacketTypesIn.EntityEquipment }, // (Wiki name: Set Equipment)
{ 0x5C, PacketTypesIn.SetExperience }, // Changed in 1.20.2
{ 0x5D, PacketTypesIn.UpdateHealth }, // (Wiki name: Set Health)
{ 0x5E, PacketTypesIn.ScoreboardObjective }, // (Wiki name: Update Objectives) - Changed in 1.20.3
{ 0x5F, PacketTypesIn.SetPassengers }, //
{ 0x60, PacketTypesIn.Teams }, // (Wiki name: Update Teams)
{ 0x61, PacketTypesIn.UpdateScore }, // (Wiki name: Update Score)
{ 0x62, PacketTypesIn.UpdateSimulationDistance }, // (Wiki name: Set Simulation Distance)
{ 0x63, PacketTypesIn.SetTitleSubTitle }, // (Wiki name: Set Subtitle Test)
{ 0x64, PacketTypesIn.TimeUpdate }, // (Wiki name: Set Time)
{ 0x65, PacketTypesIn.SetTitleText }, // (Wiki name: Set Title)
{ 0x66, PacketTypesIn.SetTitleTime }, // (Wiki name: Set Title Animation Times)
{ 0x67, PacketTypesIn.EntitySoundEffect }, // (Wiki name: Sound Entity)
{ 0x68, PacketTypesIn.SoundEffect }, // Changed in 1.19 (Added "Seed" field) (Wiki name: Sound Effect) (No need to be implemented)
{ 0x69, PacketTypesIn.StartConfiguration }, // Added in 1.20.2
{ 0x6A, PacketTypesIn.StopSound }, //
{ 0x6B, PacketTypesIn.StoreCookie }, // Added in 1.20.6
{ 0x6C, PacketTypesIn.SystemChat }, // Added in 1.19 (Wiki name: System Chat Message)
{ 0x6D, PacketTypesIn.PlayerListHeaderAndFooter }, // (Wiki name: Set Tab List Header And Footer)
{ 0x6E, PacketTypesIn.NBTQueryResponse }, // (Wiki name: Tag Query Response)
{ 0x6F, PacketTypesIn.CollectItem }, // (Wiki name: Pickup Item)
{ 0x70, PacketTypesIn.EntityTeleport }, // (Wiki name: Teleport Entity)
{ 0x71, PacketTypesIn.SetTickingState }, // Added in 1.20.3
{ 0x72, PacketTypesIn.StepTick }, // Added in 1.20.3
{ 0x73, PacketTypesIn.Transfer }, // Added in 1.20.6
{ 0x74, PacketTypesIn.Advancements }, // (Wiki name: Update Advancements) (Unused)
{ 0x75, PacketTypesIn.EntityProperties }, // (Wiki name: Update Attributes)
{ 0x76, PacketTypesIn.EntityEffect }, // Changed in 1.19 (Added "Has Factor Data" and "Factor Codec" fields) (Wiki name: Entity Effect)
{ 0x77, PacketTypesIn.DeclareRecipes }, // (Wiki name: Update Recipes) (Unused)
{ 0x78, PacketTypesIn.Tags }, // (Wiki name: Update Tags)
{ 0x79, PacketTypesIn.ProjectilePower }, // Added in 1.20.6
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation)
{ 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag)
{ 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficulty)
{ 0x03, PacketTypesOut.MessageAcknowledgment }, // Added in 1.19.1
{ 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19
{ 0x05, PacketTypesOut.SignedChatCommand }, // Added in 1.20.6
{ 0x06, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat)
{ 0x07, PacketTypesOut.PlayerSession }, // Added in 1.19.3
{ 0x08, PacketTypesOut.ChunkBatchReceived }, // Added in 1.20.2
{ 0x09, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command)
{ 0x0A, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information)
{ 0x0B, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request)
{ 0x0C, PacketTypesOut.AcknowledgeConfiguration }, // Added in 1.20.2
{ 0x0D, PacketTypesOut.ClickWindowButton }, // (Wiki name: Click Container Button)
{ 0x0E, PacketTypesOut.ClickWindow }, // (Wiki name: Click Container)
{ 0x0F, PacketTypesOut.CloseWindow }, // (Wiki name: Close Container (serverbound))
{ 0x10, PacketTypesOut.ChangeContainerSlotState }, // Added in 1.20.3
{ 0x11, PacketTypesOut.CookieResponse }, // Added in 1.20.6
{ 0x12, PacketTypesOut.PluginMessage }, // (Wiki name: Serverbound Plugin Message)
{ 0x13, PacketTypesOut.DebugSampleSubscription }, // Added in 1.20.6
{ 0x14, PacketTypesOut.EditBook }, //
{ 0x15, PacketTypesOut.EntityNBTRequest }, // (Wiki name: Query Entity Tag)
{ 0x16, PacketTypesOut.InteractEntity }, // (Wiki name: Interact)
{ 0x17, PacketTypesOut.GenerateStructure }, // (Wiki name: Jigsaw Generate)
{ 0x18, PacketTypesOut.KeepAlive }, // (Wiki name: Serverbound Keep Alive (play))
{ 0x19, PacketTypesOut.LockDifficulty }, //
{ 0x1A, PacketTypesOut.PlayerPosition }, // (Wiki name: Move Player Position)
{ 0x1B, PacketTypesOut.PlayerPositionAndRotation }, // (Wiki name: Set Player Position and Rotation)
{ 0x1C, PacketTypesOut.PlayerRotation }, // (Wiki name: Set Player Rotation)
{ 0x1D, PacketTypesOut.PlayerMovement }, // (Wiki name: Set Player On Ground)
{ 0x1E, PacketTypesOut.VehicleMove }, // (Wiki name: Move Vehicle (serverbound))
{ 0x1F, PacketTypesOut.SteerBoat }, // (Wiki name: Paddle Boat)
{ 0x20, PacketTypesOut.PickItem }, //
{ 0x21, PacketTypesOut.PingRequest }, // Added in 1.20.2
{ 0x22, PacketTypesOut.CraftRecipeRequest }, // (Wiki name: Place recipe)
{ 0x23, PacketTypesOut.PlayerAbilities }, //
{ 0x24, PacketTypesOut.PlayerDigging }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Player Action)
{ 0x25, PacketTypesOut.EntityAction }, // (Wiki name: Player Command)
{ 0x26, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input)
{ 0x27, PacketTypesOut.Pong }, // (Wiki name: Pong (play))
{ 0x28, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings)
{ 0x29, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe)
{ 0x2A, PacketTypesOut.NameItem }, // (Wiki name: Rename Item)
{ 0x2B, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound))
{ 0x2C, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements)
{ 0x2D, PacketTypesOut.SelectTrade }, //
{ 0x2E, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (No need to be implemented yet)
{ 0x2F, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound))
{ 0x30, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Program Command Block)
{ 0x31, PacketTypesOut.UpdateCommandBlockMinecart }, // (Wiki name: Program Command Block Minecart)
{ 0x32, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot)
{ 0x33, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Program Jigsaw Block)
{ 0x34, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Program Structure Block)
{ 0x35, PacketTypesOut.UpdateSign }, // (Wiki name: Update Sign)
{ 0x36, PacketTypesOut.Animation }, // (Wiki name: Swing Arm)
{ 0x37, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity)
{ 0x38, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On)
{ 0x39, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,234 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette121 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Added in 1.19.4
{ 0x01, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity)
{ 0x02, PacketTypesIn.SpawnExperienceOrb }, // (Wiki name: Spawn Exeprience Orb)
{ 0x03, PacketTypesIn.EntityAnimation }, // (Wiki name: Entity Animation (clientbound))
{ 0x04, PacketTypesIn.Statistics }, // (Wiki name: Award Statistics)
{ 0x05, PacketTypesIn.BlockChangedAck }, // Added 1.19 (Wiki name: Acknowledge Block Change)
{ 0x06, PacketTypesIn.BlockBreakAnimation }, // (Wiki name: Set Block Destroy Stage)
{ 0x07, PacketTypesIn.BlockEntityData }, //
{ 0x08, PacketTypesIn.BlockAction }, //
{ 0x09, PacketTypesIn.BlockChange }, // (Wiki name: Block Update)
{ 0x0A, PacketTypesIn.BossBar }, //
{ 0x0B, PacketTypesIn.ServerDifficulty }, // (Wiki name: Change Difficulty)
{ 0x0C, PacketTypesIn.ChunkBatchFinished }, // Added in 1.20.2
{ 0x0D, PacketTypesIn.ChunkBatchStarted }, // Added in 1.20.2
{ 0x0E, PacketTypesIn.ChunksBiomes }, // Added in 1.19.4
{ 0x0F, PacketTypesIn.ClearTiles }, //
{ 0x10, PacketTypesIn.TabComplete }, // (Wiki name: Command Suggestions Response)
{ 0x11, PacketTypesIn.DeclareCommands }, // (Wiki name: Commands)
{ 0x12, PacketTypesIn.CloseWindow }, // (Wiki name: Close Container (clientbound))
{ 0x13, PacketTypesIn.WindowItems }, // (Wiki name: Set Container Content)
{ 0x14, PacketTypesIn.WindowProperty }, // (Wiki name: Set Container Property)
{ 0x15, PacketTypesIn.SetSlot }, // (Wiki name: Set Container Slot)
{ 0x16, PacketTypesIn.CookieRequest }, // Added in 1.20.6
{ 0x17, PacketTypesIn.SetCooldown }, //
{ 0x18, PacketTypesIn.ChatSuggestions }, // Added in 1.19.1
{ 0x19, PacketTypesIn.PluginMessage }, // (Wiki name: Plugin Message (clientbound))
{ 0x1A, PacketTypesIn.DamageEvent }, // Added in 1.19.4
{ 0x1B, PacketTypesIn.DebugSample }, // Added in 1.20.6
{ 0x1C, PacketTypesIn.HideMessage }, // Added in 1.19.1
{ 0x1D, PacketTypesIn.Disconnect }, //
{ 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Added in 1.19.3 (Wiki name: Disguised Chat Message)
{ 0x1F, PacketTypesIn.EntityStatus }, // (Wiki name: Entity Event)
{ 0x20, PacketTypesIn.Explosion }, // Changed in 1.19 (Location fields are now Double instead of Float) (Wiki name: Explosion)
{ 0x21, PacketTypesIn.UnloadChunk }, // (Wiki name: Forget Chunk)
{ 0x22, PacketTypesIn.ChangeGameState }, // (Wiki name: Game Event)
{ 0x23, PacketTypesIn.OpenHorseWindow }, // (Wiki name: Horse Screen Open)
{ 0x24, PacketTypesIn.HurtAnimation }, // Added in 1.19.4
{ 0x25, PacketTypesIn.InitializeWorldBorder }, //
{ 0x26, PacketTypesIn.KeepAlive }, //
{ 0x27, PacketTypesIn.ChunkData }, //
{ 0x28, PacketTypesIn.Effect }, // (Wiki name: World Event)
{ 0x29, PacketTypesIn.Particle }, // Changed in 1.19 (Wiki name: Level Particle) (No need to be implemented)
{ 0x2A, PacketTypesIn.UpdateLight }, // (Wiki name: Light Update)
{ 0x2B, PacketTypesIn.JoinGame }, // Changed in 1.20.2 (Wiki name: Login (play))
{ 0x2C, PacketTypesIn.MapData }, // (Wiki name: Map Item Data)
{ 0x2D, PacketTypesIn.TradeList }, // (Wiki name: Merchant Offers)
{ 0x2E, PacketTypesIn.EntityPosition }, // (Wiki name: Move Entity Position)
{ 0x2F, PacketTypesIn.EntityPositionAndRotation }, // (Wiki name: Move Entity Position and Rotation)
{ 0x30, PacketTypesIn.EntityRotation }, // (Wiki name: Move Entity Rotation)
{ 0x31, PacketTypesIn.VehicleMove }, // (Wiki name: Move Vehicle)
{ 0x32, PacketTypesIn.OpenBook }, //
{ 0x33, PacketTypesIn.OpenWindow }, // (Wiki name: Open Screen)
{ 0x34, PacketTypesIn.OpenSignEditor }, //
{ 0x35, PacketTypesIn.Ping }, // (Wiki name: Ping (play))
{ 0x36, PacketTypesIn.PingResponse }, // Added in 1.20.2
{ 0x37, PacketTypesIn.CraftRecipeResponse }, // (Wiki name: Place Ghost Recipe)
{ 0x38, PacketTypesIn.PlayerAbilities }, //
{ 0x39, PacketTypesIn.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Player Chat Message)
{ 0x3A, PacketTypesIn.EndCombatEvent }, // (Wiki name: End Combat)
{ 0x3B, PacketTypesIn.EnterCombatEvent }, // (Wiki name: Enter Combat)
{ 0x3C, PacketTypesIn.DeathCombatEvent }, // (Wiki name: Combat Death)
{ 0x3D, PacketTypesIn.PlayerRemove }, // Added in 1.19.3 (Not used)
{ 0x3E, PacketTypesIn.PlayerInfo }, // Changed in 1.19 (Heavy changes)
{ 0x3F, PacketTypesIn.FacePlayer }, // (Wiki name: Player Look At)
{ 0x40, PacketTypesIn.PlayerPositionAndLook }, // (Wiki name: Synchronize Player Position)
{ 0x41, PacketTypesIn.UnlockRecipes }, // (Wiki name: Update Recipe Book)
{ 0x42, PacketTypesIn.DestroyEntities }, // (Wiki name: Remove Entites)
{ 0x43, PacketTypesIn.RemoveEntityEffect }, //
{ 0x44, PacketTypesIn.ResetScore }, // Added in 1.20.3
{ 0x45, PacketTypesIn.RemoveResourcePack }, // Added in 1.20.3
{ 0x46, PacketTypesIn.ResourcePackSend }, // (Wiki name: Add Resource pack (play))
{ 0x47, PacketTypesIn.Respawn }, // Changed in 1.20.2
{ 0x48, PacketTypesIn.EntityHeadLook }, // (Wiki name: Set Head Rotation)
{ 0x49, PacketTypesIn.MultiBlockChange }, // (Wiki name: Update Section Blocks)
{ 0x4A, PacketTypesIn.SelectAdvancementTab }, //
{ 0x4B, PacketTypesIn.ServerData }, // Added in 1.19
{ 0x4C, PacketTypesIn.ActionBar }, // (Wiki name: Set Action Bar Text)
{ 0x4D, PacketTypesIn.WorldBorderCenter }, // (Wiki name: Set Border Center)
{ 0x4E, PacketTypesIn.WorldBorderLerpSize }, //
{ 0x4F, PacketTypesIn.WorldBorderSize }, // (Wiki name: Set World Border Size)
{ 0x50, PacketTypesIn.WorldBorderWarningDelay }, // (Wiki name: Set World Border Warning Delay)
{ 0x51, PacketTypesIn.WorldBorderWarningReach }, // (Wiki name: Set Border Warning Distance)
{ 0x52, PacketTypesIn.Camera }, // (Wiki name: Set Camera)
{ 0x53, PacketTypesIn.HeldItemChange }, // (Wiki name: Set Held Item)
{ 0x54, PacketTypesIn.UpdateViewPosition }, // (Wiki name: Set Center Chunk)
{ 0x55, PacketTypesIn.UpdateViewDistance }, // (Wiki name: Set Render Distance)
{ 0x56, PacketTypesIn.SpawnPosition }, // (Wiki name: Set Default Spawn Position)
{ 0x57, PacketTypesIn.DisplayScoreboard }, // (Wiki name: Set Display Objective)
{ 0x58, PacketTypesIn.EntityMetadata }, // (Wiki name: Set Entity Metadata)
{ 0x59, PacketTypesIn.AttachEntity }, // (Wiki name: Link Entities)
{ 0x5A, PacketTypesIn.EntityVelocity }, // (Wiki name: Set Entity Velocity)
{ 0x5B, PacketTypesIn.EntityEquipment }, // (Wiki name: Set Equipment)
{ 0x5C, PacketTypesIn.SetExperience }, // Changed in 1.20.2
{ 0x5D, PacketTypesIn.UpdateHealth }, // (Wiki name: Set Health)
{ 0x5E, PacketTypesIn.ScoreboardObjective }, // (Wiki name: Update Objectives) - Changed in 1.20.3
{ 0x5F, PacketTypesIn.SetPassengers }, //
{ 0x60, PacketTypesIn.Teams }, // (Wiki name: Update Teams)
{ 0x61, PacketTypesIn.UpdateScore }, // (Wiki name: Update Score)
{ 0x62, PacketTypesIn.UpdateSimulationDistance }, // (Wiki name: Set Simulation Distance)
{ 0x63, PacketTypesIn.SetTitleSubTitle }, // (Wiki name: Set Subtitle Test)
{ 0x64, PacketTypesIn.TimeUpdate }, // (Wiki name: Set Time)
{ 0x65, PacketTypesIn.SetTitleText }, // (Wiki name: Set Title)
{ 0x66, PacketTypesIn.SetTitleTime }, // (Wiki name: Set Title Animation Times)
{ 0x67, PacketTypesIn.EntitySoundEffect }, // (Wiki name: Sound Entity)
{ 0x68, PacketTypesIn.SoundEffect }, // Changed in 1.19 (Added "Seed" field) (Wiki name: Sound Effect) (No need to be implemented)
{ 0x69, PacketTypesIn.StartConfiguration }, // Added in 1.20.2
{ 0x6A, PacketTypesIn.StopSound }, //
{ 0x6B, PacketTypesIn.StoreCookie }, // Added in 1.20.6
{ 0x6C, PacketTypesIn.SystemChat }, // Added in 1.19 (Wiki name: System Chat Message)
{ 0x6D, PacketTypesIn.PlayerListHeaderAndFooter }, // (Wiki name: Set Tab List Header And Footer)
{ 0x6E, PacketTypesIn.NBTQueryResponse }, // (Wiki name: Tag Query Response)
{ 0x6F, PacketTypesIn.CollectItem }, // (Wiki name: Pickup Item)
{ 0x70, PacketTypesIn.EntityTeleport }, // (Wiki name: Teleport Entity)
{ 0x71, PacketTypesIn.SetTickingState }, // Added in 1.20.3
{ 0x72, PacketTypesIn.StepTick }, // Added in 1.20.3
{ 0x73, PacketTypesIn.Transfer }, // Added in 1.20.6
{ 0x74, PacketTypesIn.Advancements }, // (Wiki name: Update Advancements) (Unused)
{ 0x75, PacketTypesIn.EntityProperties }, // (Wiki name: Update Attributes)
{ 0x76, PacketTypesIn.EntityEffect }, // Changed in 1.19 (Added "Has Factor Data" and "Factor Codec" fields) (Wiki name: Entity Effect)
{ 0x77, PacketTypesIn.DeclareRecipes }, // (Wiki name: Update Recipes) (Unused)
{ 0x78, PacketTypesIn.Tags }, // (Wiki name: Update Tags)
{ 0x79, PacketTypesIn.ProjectilePower }, // Added in 1.20.6
{ 0x7A, PacketTypesIn.CustomReportDetails }, // Added in 1.21
{ 0x7B, PacketTypesIn.ServerLinks } // Added in 1.21
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation)
{ 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag)
{ 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficulty)
{ 0x03, PacketTypesOut.MessageAcknowledgment }, // Added in 1.19.1
{ 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19
{ 0x05, PacketTypesOut.SignedChatCommand }, // Added in 1.20.6
{ 0x06, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat)
{ 0x07, PacketTypesOut.PlayerSession }, // Added in 1.19.3
{ 0x08, PacketTypesOut.ChunkBatchReceived }, // Added in 1.20.2
{ 0x09, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command)
{ 0x0A, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information)
{ 0x0B, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request)
{ 0x0C, PacketTypesOut.AcknowledgeConfiguration }, // Added in 1.20.2
{ 0x0D, PacketTypesOut.ClickWindowButton }, // (Wiki name: Click Container Button)
{ 0x0E, PacketTypesOut.ClickWindow }, // (Wiki name: Click Container)
{ 0x0F, PacketTypesOut.CloseWindow }, // (Wiki name: Close Container (serverbound))
{ 0x10, PacketTypesOut.ChangeContainerSlotState }, // Added in 1.20.3
{ 0x11, PacketTypesOut.CookieResponse }, // Added in 1.20.6
{ 0x12, PacketTypesOut.PluginMessage }, // (Wiki name: Serverbound Plugin Message)
{ 0x13, PacketTypesOut.DebugSampleSubscription }, // Added in 1.20.6
{ 0x14, PacketTypesOut.EditBook }, //
{ 0x15, PacketTypesOut.EntityNBTRequest }, // (Wiki name: Query Entity Tag)
{ 0x16, PacketTypesOut.InteractEntity }, // (Wiki name: Interact)
{ 0x17, PacketTypesOut.GenerateStructure }, // (Wiki name: Jigsaw Generate)
{ 0x18, PacketTypesOut.KeepAlive }, // (Wiki name: Serverbound Keep Alive (play))
{ 0x19, PacketTypesOut.LockDifficulty }, //
{ 0x1A, PacketTypesOut.PlayerPosition }, // (Wiki name: Move Player Position)
{ 0x1B, PacketTypesOut.PlayerPositionAndRotation }, // (Wiki name: Set Player Position and Rotation)
{ 0x1C, PacketTypesOut.PlayerRotation }, // (Wiki name: Set Player Rotation)
{ 0x1D, PacketTypesOut.PlayerMovement }, // (Wiki name: Set Player On Ground)
{ 0x1E, PacketTypesOut.VehicleMove }, // (Wiki name: Move Vehicle (serverbound))
{ 0x1F, PacketTypesOut.SteerBoat }, // (Wiki name: Paddle Boat)
{ 0x20, PacketTypesOut.PickItem }, //
{ 0x21, PacketTypesOut.PingRequest }, // Added in 1.20.2
{ 0x22, PacketTypesOut.CraftRecipeRequest }, // (Wiki name: Place recipe)
{ 0x23, PacketTypesOut.PlayerAbilities }, //
{ 0x24, PacketTypesOut.PlayerDigging }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Player Action)
{ 0x25, PacketTypesOut.EntityAction }, // (Wiki name: Player Command)
{ 0x26, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input)
{ 0x27, PacketTypesOut.Pong }, // (Wiki name: Pong (play))
{ 0x28, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings)
{ 0x29, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe)
{ 0x2A, PacketTypesOut.NameItem }, // (Wiki name: Rename Item)
{ 0x2B, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound))
{ 0x2C, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements)
{ 0x2D, PacketTypesOut.SelectTrade }, //
{ 0x2E, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (No need to be implemented yet)
{ 0x2F, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound))
{ 0x30, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Program Command Block)
{ 0x31, PacketTypesOut.UpdateCommandBlockMinecart }, // (Wiki name: Program Command Block Minecart)
{ 0x32, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot)
{ 0x33, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Program Jigsaw Block)
{ 0x34, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Program Structure Block)
{ 0x35, PacketTypesOut.UpdateSign }, // (Wiki name: Update Sign)
{ 0x36, PacketTypesOut.Animation }, // (Wiki name: Swing Arm)
{ 0x37, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity)
{ 0x38, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On)
{ 0x39, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item)
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, // Added in 1.21 (Not used)
{ 0x10, ConfigurationPacketTypesIn.ServerLinks } // Added in 1.21 (Not used)
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,243 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1212 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.SpawnExperienceOrb }, // Add Experience Orb
{ 0x03, PacketTypesIn.EntityAnimation }, // Animate
{ 0x04, PacketTypesIn.Statistics }, // Award Stats
{ 0x05, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x06, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x07, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x08, PacketTypesIn.BlockAction }, // Block Event
{ 0x09, PacketTypesIn.BlockChange }, // Block Update
{ 0x0A, PacketTypesIn.BossBar }, // Boss Event
{ 0x0B, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0C, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0D, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0E, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0F, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x10, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x11, PacketTypesIn.DeclareCommands }, // Commands
{ 0x12, PacketTypesIn.CloseWindow }, // Container Close
{ 0x13, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x14, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x15, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x16, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x17, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x18, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x19, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x1A, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1B, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1C, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x1D, PacketTypesIn.Disconnect }, // Disconnect
{ 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x1F, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x20, PacketTypesIn.EntityPositionSync }, // Entity Position Sync (new in 1.21.2)
{ 0x21, PacketTypesIn.Explosion }, // Explode
{ 0x22, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x23, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x24, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open
{ 0x25, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x26, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x27, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x28, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x29, PacketTypesIn.Effect }, // Level Event
{ 0x2A, PacketTypesIn.Particle }, // Level Particles
{ 0x2B, PacketTypesIn.UpdateLight }, // Light Update
{ 0x2C, PacketTypesIn.JoinGame }, // Login
{ 0x2D, PacketTypesIn.MapData }, // Map Item Data
{ 0x2E, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x2F, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x30, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x31, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track (new in 1.21.2)
{ 0x32, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x33, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x34, PacketTypesIn.OpenBook }, // Open Book
{ 0x35, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x36, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x37, PacketTypesIn.Ping }, // Ping
{ 0x38, PacketTypesIn.PingResponse }, // Pong Response
{ 0x39, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x3A, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x3B, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x3C, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x3D, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x3E, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x3F, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x40, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x41, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x42, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x43, PacketTypesIn.PlayerRotation }, // Player Rotation (new in 1.21.2)
{ 0x44, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add (new in 1.21.2, replaces UnlockRecipes)
{ 0x45, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove (new in 1.21.2)
{ 0x46, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings (new in 1.21.2)
{ 0x47, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x48, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x49, PacketTypesIn.ResetScore }, // Reset Score
{ 0x4A, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x4B, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x4C, PacketTypesIn.Respawn }, // Respawn
{ 0x4D, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x4E, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x4F, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x50, PacketTypesIn.ServerData }, // Server Data
{ 0x51, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x52, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x53, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x54, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x55, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x56, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x57, PacketTypesIn.Camera }, // Set Camera
{ 0x58, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x59, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x5A, PacketTypesIn.SetCursorItem }, // Set Cursor Item (new in 1.21.2)
{ 0x5B, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x5C, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x5D, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x5E, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x5F, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x60, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x61, PacketTypesIn.SetExperience }, // Set Experience
{ 0x62, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x63, PacketTypesIn.SetHeldSlot }, // Set Held Slot (new in 1.21.2, replaces HeldItemChange)
{ 0x64, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x65, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x66, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory (new in 1.21.2)
{ 0x67, PacketTypesIn.Teams }, // Set Player Team
{ 0x68, PacketTypesIn.UpdateScore }, // Set Score
{ 0x69, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x6A, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x6B, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x6C, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x6D, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x6E, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x6F, PacketTypesIn.SoundEffect }, // Sound
{ 0x70, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x71, PacketTypesIn.StopSound }, // Stop Sound
{ 0x72, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x73, PacketTypesIn.SystemChat }, // System Chat
{ 0x74, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x75, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x76, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x77, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x78, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x79, PacketTypesIn.StepTick }, // Ticking Step
{ 0x7A, PacketTypesIn.Transfer }, // Transfer
{ 0x7B, PacketTypesIn.Advancements }, // Update Advancements
{ 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x7F, PacketTypesIn.Tags }, // Update Tags
{ 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x82, PacketTypesIn.ServerLinks } // Server Links
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected (new in 1.21.2)
{ 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x05, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x07, PacketTypesOut.ChatMessage }, // Chat
{ 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0A, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End (new in 1.21.2)
{ 0x0C, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x10, PacketTypesOut.ClickWindow }, // Container Click
{ 0x11, PacketTypesOut.CloseWindow }, // Container Close
{ 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x13, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x14, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription
{ 0x16, PacketTypesOut.EditBook }, // Edit Book
{ 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x18, PacketTypesOut.InteractEntity }, // Interact
{ 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x22, PacketTypesOut.PickItem }, // Pick Item
{ 0x23, PacketTypesOut.PingRequest }, // Ping Request
{ 0x24, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x25, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x26, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x27, PacketTypesOut.EntityAction }, // Player Command
{ 0x28, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x29, PacketTypesOut.Pong }, // Pong
{ 0x2A, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2B, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x2C, PacketTypesOut.NameItem }, // Rename Item
{ 0x2D, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x2E, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x2F, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x30, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x31, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x32, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x33, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x34, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x35, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x36, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x37, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x38, PacketTypesOut.Animation }, // Swing
{ 0x39, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x3A, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x3B, PacketTypesOut.UseItem }, // Use Item
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks }
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,245 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1214 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.SpawnExperienceOrb }, // Add Experience Orb
{ 0x03, PacketTypesIn.EntityAnimation }, // Animate
{ 0x04, PacketTypesIn.Statistics }, // Award Stats
{ 0x05, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x06, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x07, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x08, PacketTypesIn.BlockAction }, // Block Event
{ 0x09, PacketTypesIn.BlockChange }, // Block Update
{ 0x0A, PacketTypesIn.BossBar }, // Boss Event
{ 0x0B, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0C, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0D, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0E, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0F, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x10, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x11, PacketTypesIn.DeclareCommands }, // Commands
{ 0x12, PacketTypesIn.CloseWindow }, // Container Close
{ 0x13, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x14, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x15, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x16, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x17, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x18, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x19, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x1A, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1B, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1C, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x1D, PacketTypesIn.Disconnect }, // Disconnect
{ 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x1F, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x20, PacketTypesIn.EntityPositionSync }, // Entity Position Sync (new in 1.21.2)
{ 0x21, PacketTypesIn.Explosion }, // Explode
{ 0x22, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x23, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x24, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open
{ 0x25, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x26, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x27, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x28, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x29, PacketTypesIn.Effect }, // Level Event
{ 0x2A, PacketTypesIn.Particle }, // Level Particles
{ 0x2B, PacketTypesIn.UpdateLight }, // Light Update
{ 0x2C, PacketTypesIn.JoinGame }, // Login
{ 0x2D, PacketTypesIn.MapData }, // Map Item Data
{ 0x2E, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x2F, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x30, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x31, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track (new in 1.21.2)
{ 0x32, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x33, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x34, PacketTypesIn.OpenBook }, // Open Book
{ 0x35, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x36, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x37, PacketTypesIn.Ping }, // Ping
{ 0x38, PacketTypesIn.PingResponse }, // Pong Response
{ 0x39, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x3A, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x3B, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x3C, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x3D, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x3E, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x3F, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x40, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x41, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x42, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x43, PacketTypesIn.PlayerRotation }, // Player Rotation (new in 1.21.2)
{ 0x44, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add (new in 1.21.2, replaces UnlockRecipes)
{ 0x45, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove (new in 1.21.2)
{ 0x46, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings (new in 1.21.2)
{ 0x47, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x48, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x49, PacketTypesIn.ResetScore }, // Reset Score
{ 0x4A, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x4B, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x4C, PacketTypesIn.Respawn }, // Respawn
{ 0x4D, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x4E, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x4F, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x50, PacketTypesIn.ServerData }, // Server Data
{ 0x51, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x52, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x53, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x54, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x55, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x56, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x57, PacketTypesIn.Camera }, // Set Camera
{ 0x58, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x59, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x5A, PacketTypesIn.SetCursorItem }, // Set Cursor Item (new in 1.21.2)
{ 0x5B, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x5C, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x5D, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x5E, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x5F, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x60, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x61, PacketTypesIn.SetExperience }, // Set Experience
{ 0x62, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x63, PacketTypesIn.SetHeldSlot }, // Set Held Slot (new in 1.21.2, replaces HeldItemChange)
{ 0x64, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x65, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x66, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory (new in 1.21.2)
{ 0x67, PacketTypesIn.Teams }, // Set Player Team
{ 0x68, PacketTypesIn.UpdateScore }, // Set Score
{ 0x69, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x6A, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x6B, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x6C, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x6D, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x6E, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x6F, PacketTypesIn.SoundEffect }, // Sound
{ 0x70, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x71, PacketTypesIn.StopSound }, // Stop Sound
{ 0x72, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x73, PacketTypesIn.SystemChat }, // System Chat
{ 0x74, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x75, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x76, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x77, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x78, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x79, PacketTypesIn.StepTick }, // Ticking Step
{ 0x7A, PacketTypesIn.Transfer }, // Transfer
{ 0x7B, PacketTypesIn.Advancements }, // Update Advancements
{ 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x7F, PacketTypesIn.Tags }, // Update Tags
{ 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x82, PacketTypesIn.ServerLinks } // Server Links
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected
{ 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x05, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x07, PacketTypesOut.ChatMessage }, // Chat
{ 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0A, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End
{ 0x0C, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x10, PacketTypesOut.ClickWindow }, // Container Click
{ 0x11, PacketTypesOut.CloseWindow }, // Container Close
{ 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x13, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x14, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription
{ 0x16, PacketTypesOut.EditBook }, // Edit Book
{ 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x18, PacketTypesOut.InteractEntity }, // Interact
{ 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x22, PacketTypesOut.PickItem }, // Pick Item From Block (split in 1.21.4)
{ 0x23, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity (new in 1.21.4)
{ 0x24, PacketTypesOut.PingRequest }, // Ping Request
{ 0x25, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x26, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x27, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x28, PacketTypesOut.EntityAction }, // Player Command
{ 0x29, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x2A, PacketTypesOut.PlayerLoaded }, // Player Loaded (new in 1.21.4)
{ 0x2B, PacketTypesOut.Pong }, // Pong
{ 0x2C, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2D, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x2E, PacketTypesOut.NameItem }, // Rename Item
{ 0x2F, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x30, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x31, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x32, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x33, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x34, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x35, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x36, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x37, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x38, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x39, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x3A, PacketTypesOut.Animation }, // Swing
{ 0x3B, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x3C, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x3D, PacketTypesOut.UseItem }, // Use Item
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks }
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,247 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1215 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.EntityAnimation }, // Animate (was 0x03 in 1.21.4; AddExperienceOrb removed)
{ 0x03, PacketTypesIn.Statistics }, // Award Stats
{ 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x07, PacketTypesIn.BlockAction }, // Block Event
{ 0x08, PacketTypesIn.BlockChange }, // Block Update
{ 0x09, PacketTypesIn.BossBar }, // Boss Event
{ 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x10, PacketTypesIn.DeclareCommands }, // Commands
{ 0x11, PacketTypesIn.CloseWindow }, // Container Close
{ 0x12, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x13, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x14, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x15, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x16, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x18, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x19, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1A, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1B, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x1C, PacketTypesIn.Disconnect }, // Disconnect
{ 0x1D, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x1E, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x1F, PacketTypesIn.EntityPositionSync }, // Entity Position Sync
{ 0x20, PacketTypesIn.Explosion }, // Explode
{ 0x21, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x22, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x23, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open
{ 0x24, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x25, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x26, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x27, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x28, PacketTypesIn.Effect }, // Level Event
{ 0x29, PacketTypesIn.Particle }, // Level Particles
{ 0x2A, PacketTypesIn.UpdateLight }, // Light Update
{ 0x2B, PacketTypesIn.JoinGame }, // Login
{ 0x2C, PacketTypesIn.MapData }, // Map Item Data
{ 0x2D, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x2E, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x2F, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x30, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track
{ 0x31, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x32, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x33, PacketTypesIn.OpenBook }, // Open Book
{ 0x34, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x35, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x36, PacketTypesIn.Ping }, // Ping
{ 0x37, PacketTypesIn.PingResponse }, // Pong Response
{ 0x38, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x39, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x3A, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x3B, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x3C, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x3D, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x3E, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x3F, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x40, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x41, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x42, PacketTypesIn.PlayerRotation }, // Player Rotation
{ 0x43, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add
{ 0x44, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove
{ 0x45, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings
{ 0x46, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x47, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x48, PacketTypesIn.ResetScore }, // Reset Score
{ 0x49, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x4A, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x4B, PacketTypesIn.Respawn }, // Respawn
{ 0x4C, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x4D, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x4E, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x4F, PacketTypesIn.ServerData }, // Server Data
{ 0x50, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x51, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x52, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x53, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x54, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x55, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x56, PacketTypesIn.Camera }, // Set Camera
{ 0x57, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x58, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x59, PacketTypesIn.SetCursorItem }, // Set Cursor Item
{ 0x5A, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x5B, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x5C, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x5D, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x5E, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x5F, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x60, PacketTypesIn.SetExperience }, // Set Experience
{ 0x61, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x62, PacketTypesIn.SetHeldSlot }, // Set Held Slot
{ 0x63, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x64, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x65, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory
{ 0x66, PacketTypesIn.Teams }, // Set Player Team
{ 0x67, PacketTypesIn.UpdateScore }, // Set Score
{ 0x68, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x69, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x6A, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x6B, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x6C, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x6D, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x6E, PacketTypesIn.SoundEffect }, // Sound
{ 0x6F, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x70, PacketTypesIn.StopSound }, // Stop Sound
{ 0x71, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x72, PacketTypesIn.SystemChat }, // System Chat
{ 0x73, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x74, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x75, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x76, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x77, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status (new in 1.21.5)
{ 0x78, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x79, PacketTypesIn.StepTick }, // Ticking Step
{ 0x7A, PacketTypesIn.Transfer }, // Transfer
{ 0x7B, PacketTypesIn.Advancements }, // Update Advancements
{ 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x7F, PacketTypesIn.Tags }, // Update Tags
{ 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x82, PacketTypesIn.ServerLinks } // Server Links
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected
{ 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x05, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x07, PacketTypesOut.ChatMessage }, // Chat
{ 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0A, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End
{ 0x0C, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x10, PacketTypesOut.ClickWindow }, // Container Click
{ 0x11, PacketTypesOut.CloseWindow }, // Container Close
{ 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x13, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x14, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription
{ 0x16, PacketTypesOut.EditBook }, // Edit Book
{ 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x18, PacketTypesOut.InteractEntity }, // Interact
{ 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x22, PacketTypesOut.PickItem }, // Pick Item From Block
{ 0x23, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity
{ 0x24, PacketTypesOut.PingRequest }, // Ping Request
{ 0x25, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x26, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x27, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x28, PacketTypesOut.EntityAction }, // Player Command
{ 0x29, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x2A, PacketTypesOut.PlayerLoaded }, // Player Loaded
{ 0x2B, PacketTypesOut.Pong }, // Pong
{ 0x2C, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2D, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x2E, PacketTypesOut.NameItem }, // Rename Item
{ 0x2F, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x30, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x31, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x32, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x33, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x34, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x35, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x36, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x37, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x38, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x39, PacketTypesOut.SetTestBlock }, // Set Test Block (new in 1.21.5)
{ 0x3A, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x3B, PacketTypesOut.Animation }, // Swing
{ 0x3C, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x3D, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action (new in 1.21.5)
{ 0x3E, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x3F, PacketTypesOut.UseItem }, // Use Item
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks }
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,255 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1216 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.EntityAnimation }, // Animate
{ 0x03, PacketTypesIn.Statistics }, // Award Stats
{ 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x07, PacketTypesIn.BlockAction }, // Block Event
{ 0x08, PacketTypesIn.BlockChange }, // Block Update
{ 0x09, PacketTypesIn.BossBar }, // Boss Event
{ 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x10, PacketTypesIn.DeclareCommands }, // Commands
{ 0x11, PacketTypesIn.CloseWindow }, // Container Close
{ 0x12, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x13, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x14, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x15, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x16, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x18, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x19, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1A, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1B, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x1C, PacketTypesIn.Disconnect }, // Disconnect
{ 0x1D, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x1E, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x1F, PacketTypesIn.EntityPositionSync }, // Entity Position Sync
{ 0x20, PacketTypesIn.Explosion }, // Explode
{ 0x21, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x22, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x23, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open
{ 0x24, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x25, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x26, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x27, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x28, PacketTypesIn.Effect }, // Level Event
{ 0x29, PacketTypesIn.Particle }, // Level Particles
{ 0x2A, PacketTypesIn.UpdateLight }, // Light Update
{ 0x2B, PacketTypesIn.JoinGame }, // Login
{ 0x2C, PacketTypesIn.MapData }, // Map Item Data
{ 0x2D, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x2E, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x2F, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x30, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track
{ 0x31, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x32, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x33, PacketTypesIn.OpenBook }, // Open Book
{ 0x34, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x35, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x36, PacketTypesIn.Ping }, // Ping
{ 0x37, PacketTypesIn.PingResponse }, // Pong Response
{ 0x38, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x39, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x3A, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x3B, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x3C, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x3D, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x3E, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x3F, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x40, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x41, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x42, PacketTypesIn.PlayerRotation }, // Player Rotation
{ 0x43, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add
{ 0x44, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove
{ 0x45, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings
{ 0x46, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x47, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x48, PacketTypesIn.ResetScore }, // Reset Score
{ 0x49, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x4A, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x4B, PacketTypesIn.Respawn }, // Respawn
{ 0x4C, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x4D, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x4E, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x4F, PacketTypesIn.ServerData }, // Server Data
{ 0x50, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x51, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x52, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x53, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x54, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x55, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x56, PacketTypesIn.Camera }, // Set Camera
{ 0x57, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x58, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x59, PacketTypesIn.SetCursorItem }, // Set Cursor Item
{ 0x5A, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x5B, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x5C, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x5D, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x5E, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x5F, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x60, PacketTypesIn.SetExperience }, // Set Experience
{ 0x61, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x62, PacketTypesIn.SetHeldSlot }, // Set Held Slot
{ 0x63, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x64, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x65, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory
{ 0x66, PacketTypesIn.Teams }, // Set Player Team
{ 0x67, PacketTypesIn.UpdateScore }, // Set Score
{ 0x68, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x69, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x6A, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x6B, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x6C, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x6D, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x6E, PacketTypesIn.SoundEffect }, // Sound
{ 0x6F, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x70, PacketTypesIn.StopSound }, // Stop Sound
{ 0x71, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x72, PacketTypesIn.SystemChat }, // System Chat
{ 0x73, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x74, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x75, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x76, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x77, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status
{ 0x78, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x79, PacketTypesIn.StepTick }, // Ticking Step
{ 0x7A, PacketTypesIn.Transfer }, // Transfer
{ 0x7B, PacketTypesIn.Advancements }, // Update Advancements
{ 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x7F, PacketTypesIn.Tags }, // Update Tags
{ 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x82, PacketTypesIn.ServerLinks }, // Server Links
{ 0x83, PacketTypesIn.Waypoint }, // Waypoint (new in 1.21.6)
{ 0x84, PacketTypesIn.ClearDialog }, // Clear Dialog (new in 1.21.6)
{ 0x85, PacketTypesIn.ShowDialog } // Show Dialog (new in 1.21.6)
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected
{ 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x04, PacketTypesOut.ChangeGameMode }, // Change Game Mode (new in 1.21.6)
{ 0x05, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x06, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x07, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x08, PacketTypesOut.ChatMessage }, // Chat
{ 0x09, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x0A, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0B, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0C, PacketTypesOut.ClientTickEnd }, // Client Tick End
{ 0x0D, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0E, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x0F, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x10, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x11, PacketTypesOut.ClickWindow }, // Container Click
{ 0x12, PacketTypesOut.CloseWindow }, // Container Close
{ 0x13, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x14, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x15, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x16, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription
{ 0x17, PacketTypesOut.EditBook }, // Edit Book
{ 0x18, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x19, PacketTypesOut.InteractEntity }, // Interact
{ 0x1A, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1B, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1C, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1D, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1E, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x1F, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x20, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x21, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x22, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x23, PacketTypesOut.PickItem }, // Pick Item From Block
{ 0x24, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity
{ 0x25, PacketTypesOut.PingRequest }, // Ping Request
{ 0x26, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x27, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x28, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x29, PacketTypesOut.EntityAction }, // Player Command
{ 0x2A, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x2B, PacketTypesOut.PlayerLoaded }, // Player Loaded
{ 0x2C, PacketTypesOut.Pong }, // Pong
{ 0x2D, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2E, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x2F, PacketTypesOut.NameItem }, // Rename Item
{ 0x30, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x31, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x32, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x33, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x34, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x35, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x36, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x37, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x38, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x39, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x3A, PacketTypesOut.SetTestBlock }, // Set Test Block
{ 0x3B, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x3C, PacketTypesOut.Animation }, // Swing
{ 0x3D, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x3E, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action
{ 0x3F, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x40, PacketTypesOut.UseItem }, // Use Item
{ 0x41, PacketTypesOut.CustomClickAction } // Custom Click Action (new in 1.21.6)
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks },
{ 0x11, ConfigurationPacketTypesIn.ClearDialog }, // New in 1.21.6
{ 0x12, ConfigurationPacketTypesIn.ShowDialog } // New in 1.21.6
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks },
{ 0x08, ConfigurationPacketTypesOut.CustomClickAction } // New in 1.21.6
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -0,0 +1,262 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette1219 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.EntityAnimation }, // Animate
{ 0x03, PacketTypesIn.Statistics }, // Award Stats
{ 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x07, PacketTypesIn.BlockAction }, // Block Event
{ 0x08, PacketTypesIn.BlockChange }, // Block Update
{ 0x09, PacketTypesIn.BossBar }, // Boss Event
{ 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x10, PacketTypesIn.DeclareCommands }, // Commands
{ 0x11, PacketTypesIn.CloseWindow }, // Container Close
{ 0x12, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x13, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x14, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x15, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x16, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x18, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x19, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1A, PacketTypesIn.DebugBlockValue }, // Debug Block Value (new in 1.21.9)
{ 0x1B, PacketTypesIn.DebugChunkValue }, // Debug Chunk Value (new in 1.21.9)
{ 0x1C, PacketTypesIn.DebugEntityValue }, // Debug Entity Value (new in 1.21.9)
{ 0x1D, PacketTypesIn.DebugEvent }, // Debug Event (new in 1.21.9)
{ 0x1E, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1F, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x20, PacketTypesIn.Disconnect }, // Disconnect
{ 0x21, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x22, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x23, PacketTypesIn.EntityPositionSync }, // Entity Position Sync
{ 0x24, PacketTypesIn.Explosion }, // Explode
{ 0x25, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x26, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x27, PacketTypesIn.GameTestHighlightPos }, // Game Test Highlight Pos (new in 1.21.9)
{ 0x28, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open
{ 0x29, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x2A, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x2B, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x2C, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x2D, PacketTypesIn.Effect }, // Level Event
{ 0x2E, PacketTypesIn.Particle }, // Level Particles
{ 0x2F, PacketTypesIn.UpdateLight }, // Light Update
{ 0x30, PacketTypesIn.JoinGame }, // Login
{ 0x31, PacketTypesIn.MapData }, // Map Item Data
{ 0x32, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x33, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x34, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x35, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track
{ 0x36, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x37, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x38, PacketTypesIn.OpenBook }, // Open Book
{ 0x39, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x3A, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x3B, PacketTypesIn.Ping }, // Ping
{ 0x3C, PacketTypesIn.PingResponse }, // Pong Response
{ 0x3D, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x3E, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x3F, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x40, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x41, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x42, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x43, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x44, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x45, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x46, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x47, PacketTypesIn.PlayerRotation }, // Player Rotation
{ 0x48, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add
{ 0x49, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove
{ 0x4A, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings
{ 0x4B, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x4C, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x4D, PacketTypesIn.ResetScore }, // Reset Score
{ 0x4E, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x4F, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x50, PacketTypesIn.Respawn }, // Respawn
{ 0x51, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x52, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x53, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x54, PacketTypesIn.ServerData }, // Server Data
{ 0x55, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x56, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x57, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x58, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x59, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x5A, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x5B, PacketTypesIn.Camera }, // Set Camera
{ 0x5C, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x5D, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x5E, PacketTypesIn.SetCursorItem }, // Set Cursor Item
{ 0x5F, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x60, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x61, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x62, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x63, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x64, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x65, PacketTypesIn.SetExperience }, // Set Experience
{ 0x66, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x67, PacketTypesIn.SetHeldSlot }, // Set Held Slot
{ 0x68, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x69, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x6A, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory
{ 0x6B, PacketTypesIn.Teams }, // Set Player Team
{ 0x6C, PacketTypesIn.UpdateScore }, // Set Score
{ 0x6D, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x6E, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x6F, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x70, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x71, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x72, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x73, PacketTypesIn.SoundEffect }, // Sound
{ 0x74, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x75, PacketTypesIn.StopSound }, // Stop Sound
{ 0x76, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x77, PacketTypesIn.SystemChat }, // System Chat
{ 0x78, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x79, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x7A, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x7B, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x7C, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status
{ 0x7D, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x7E, PacketTypesIn.StepTick }, // Ticking Step
{ 0x7F, PacketTypesIn.Transfer }, // Transfer
{ 0x80, PacketTypesIn.Advancements }, // Update Advancements
{ 0x81, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x82, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x83, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x84, PacketTypesIn.Tags }, // Update Tags
{ 0x85, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x86, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x87, PacketTypesIn.ServerLinks }, // Server Links
{ 0x88, PacketTypesIn.Waypoint }, // Waypoint
{ 0x89, PacketTypesIn.ClearDialog }, // Clear Dialog
{ 0x8A, PacketTypesIn.ShowDialog } // Show Dialog
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected
{ 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x04, PacketTypesOut.ChangeGameMode }, // Change Game Mode
{ 0x05, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x06, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x07, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x08, PacketTypesOut.ChatMessage }, // Chat
{ 0x09, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x0A, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0B, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0C, PacketTypesOut.ClientTickEnd }, // Client Tick End
{ 0x0D, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0E, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x0F, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x10, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x11, PacketTypesOut.ClickWindow }, // Container Click
{ 0x12, PacketTypesOut.CloseWindow }, // Container Close
{ 0x13, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x14, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x15, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x16, PacketTypesOut.DebugSampleSubscription }, // Debug Subscription Request
{ 0x17, PacketTypesOut.EditBook }, // Edit Book
{ 0x18, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x19, PacketTypesOut.InteractEntity }, // Interact
{ 0x1A, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1B, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1C, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1D, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1E, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x1F, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x20, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x21, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x22, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x23, PacketTypesOut.PickItem }, // Pick Item From Block
{ 0x24, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity
{ 0x25, PacketTypesOut.PingRequest }, // Ping Request
{ 0x26, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x27, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x28, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x29, PacketTypesOut.EntityAction }, // Player Command
{ 0x2A, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x2B, PacketTypesOut.PlayerLoaded }, // Player Loaded
{ 0x2C, PacketTypesOut.Pong }, // Pong
{ 0x2D, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2E, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x2F, PacketTypesOut.NameItem }, // Rename Item
{ 0x30, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x31, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x32, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x33, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x34, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x35, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x36, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x37, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x38, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x39, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x3A, PacketTypesOut.SetTestBlock }, // Set Test Block
{ 0x3B, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x3C, PacketTypesOut.Animation }, // Swing
{ 0x3D, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x3E, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action
{ 0x3F, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x40, PacketTypesOut.UseItem }, // Use Item
{ 0x41, PacketTypesOut.CustomClickAction } // Custom Click Action
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks },
{ 0x11, ConfigurationPacketTypesIn.ClearDialog },
{ 0x12, ConfigurationPacketTypesIn.ShowDialog },
{ 0x13, ConfigurationPacketTypesIn.CodeOfConduct } // New in 1.21.9
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks },
{ 0x08, ConfigurationPacketTypesOut.CustomClickAction },
{ 0x09, ConfigurationPacketTypesOut.AcceptCodeOfConduct } // New in 1.21.9
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -114,7 +114,7 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => new();
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => new();
}

View file

@ -4,7 +4,7 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{
public class PacketPalette18 : PacketTypePalette
{
private Dictionary<int, PacketTypesIn> typeIn = new Dictionary<int, PacketTypesIn>()
private Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.KeepAlive },
{ 0x01, PacketTypesIn.JoinGame },
@ -80,7 +80,7 @@ namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ 0x49, PacketTypesIn.UpdateEntityNBT }
};
private Dictionary<int, PacketTypesOut> typeOut = new Dictionary<int, PacketTypesOut>()
private Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm },
{ 0x01, PacketTypesOut.Unknown },

View file

@ -0,0 +1,127 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{
public class PacketPalette19 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.SpawnEntity },
{ 0x01, PacketTypesIn.SpawnExperienceOrb },
{ 0x02, PacketTypesIn.SpawnWeatherEntity },
{ 0x03, PacketTypesIn.SpawnLivingEntity },
{ 0x04, PacketTypesIn.SpawnPainting },
{ 0x05, PacketTypesIn.SpawnPlayer },
{ 0x06, PacketTypesIn.EntityAnimation },
{ 0x07, PacketTypesIn.Statistics },
{ 0x08, PacketTypesIn.BlockBreakAnimation },
{ 0x09, PacketTypesIn.BlockEntityData },
{ 0x0A, PacketTypesIn.BlockAction },
{ 0x0B, PacketTypesIn.BlockChange },
{ 0x0C, PacketTypesIn.BossBar },
{ 0x0D, PacketTypesIn.ServerDifficulty },
{ 0x0E, PacketTypesIn.TabComplete },
{ 0x0F, PacketTypesIn.ChatMessage },
{ 0x10, PacketTypesIn.MultiBlockChange },
{ 0x11, PacketTypesIn.WindowConfirmation },
{ 0x12, PacketTypesIn.CloseWindow },
{ 0x13, PacketTypesIn.OpenWindow },
{ 0x14, PacketTypesIn.WindowItems },
{ 0x15, PacketTypesIn.WindowProperty },
{ 0x16, PacketTypesIn.SetSlot },
{ 0x17, PacketTypesIn.SetCooldown },
{ 0x18, PacketTypesIn.PluginMessage },
{ 0x19, PacketTypesIn.NamedSoundEffect },
{ 0x1A, PacketTypesIn.Disconnect },
{ 0x1B, PacketTypesIn.EntityStatus },
{ 0x1C, PacketTypesIn.Explosion },
{ 0x1D, PacketTypesIn.UnloadChunk },
{ 0x1E, PacketTypesIn.ChangeGameState },
{ 0x1F, PacketTypesIn.KeepAlive },
{ 0x20, PacketTypesIn.ChunkData },
{ 0x21, PacketTypesIn.Effect },
{ 0x22, PacketTypesIn.Particle },
{ 0x23, PacketTypesIn.JoinGame },
{ 0x24, PacketTypesIn.MapData },
{ 0x25, PacketTypesIn.EntityPosition },
{ 0x26, PacketTypesIn.EntityPositionAndRotation },
{ 0x27, PacketTypesIn.EntityRotation },
{ 0x28, PacketTypesIn.EntityMovement },
{ 0x29, PacketTypesIn.VehicleMove },
{ 0x2A, PacketTypesIn.OpenSignEditor },
{ 0x2B, PacketTypesIn.PlayerAbilities },
{ 0x2C, PacketTypesIn.CombatEvent },
{ 0x2D, PacketTypesIn.PlayerInfo },
{ 0x2E, PacketTypesIn.PlayerPositionAndLook },
{ 0x2F, PacketTypesIn.UseBed },
{ 0x30, PacketTypesIn.DestroyEntities },
{ 0x31, PacketTypesIn.RemoveEntityEffect },
{ 0x32, PacketTypesIn.ResourcePackSend },
{ 0x33, PacketTypesIn.Respawn },
{ 0x34, PacketTypesIn.EntityHeadLook },
{ 0x35, PacketTypesIn.WorldBorder },
{ 0x36, PacketTypesIn.Camera },
{ 0x37, PacketTypesIn.HeldItemChange },
{ 0x38, PacketTypesIn.DisplayScoreboard },
{ 0x39, PacketTypesIn.EntityMetadata },
{ 0x3A, PacketTypesIn.AttachEntity },
{ 0x3B, PacketTypesIn.EntityVelocity },
{ 0x3C, PacketTypesIn.EntityEquipment },
{ 0x3D, PacketTypesIn.SetExperience },
{ 0x3E, PacketTypesIn.UpdateHealth },
{ 0x3F, PacketTypesIn.ScoreboardObjective },
{ 0x40, PacketTypesIn.SetPassengers },
{ 0x41, PacketTypesIn.Teams },
{ 0x42, PacketTypesIn.UpdateScore },
{ 0x43, PacketTypesIn.SpawnPosition },
{ 0x44, PacketTypesIn.TimeUpdate },
{ 0x45, PacketTypesIn.Title },
{ 0x46, PacketTypesIn.UpdateSign },
{ 0x47, PacketTypesIn.SoundEffect },
{ 0x48, PacketTypesIn.PlayerListHeaderAndFooter },
{ 0x49, PacketTypesIn.CollectItem },
{ 0x4A, PacketTypesIn.EntityTeleport },
{ 0x4B, PacketTypesIn.EntityProperties },
{ 0x4C, PacketTypesIn.EntityEffect },
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm },
{ 0x01, PacketTypesOut.TabComplete },
{ 0x02, PacketTypesOut.ChatMessage },
{ 0x03, PacketTypesOut.ClientStatus },
{ 0x04, PacketTypesOut.ClientSettings },
{ 0x05, PacketTypesOut.WindowConfirmation },
{ 0x06, PacketTypesOut.EnchantItem },
{ 0x07, PacketTypesOut.ClickWindow },
{ 0x08, PacketTypesOut.CloseWindow },
{ 0x09, PacketTypesOut.PluginMessage },
{ 0x0A, PacketTypesOut.InteractEntity },
{ 0x0B, PacketTypesOut.KeepAlive },
{ 0x0C, PacketTypesOut.PlayerPosition },
{ 0x0D, PacketTypesOut.PlayerPositionAndRotation },
{ 0x0E, PacketTypesOut.PlayerRotation },
{ 0x0F, PacketTypesOut.PlayerMovement },
{ 0x10, PacketTypesOut.VehicleMove },
{ 0x11, PacketTypesOut.SteerBoat },
{ 0x12, PacketTypesOut.PlayerAbilities },
{ 0x13, PacketTypesOut.PlayerDigging },
{ 0x14, PacketTypesOut.EntityAction },
{ 0x15, PacketTypesOut.SteerVehicle },
{ 0x16, PacketTypesOut.ResourcePackStatus },
{ 0x17, PacketTypesOut.HeldItemChange },
{ 0x18, PacketTypesOut.CreativeInventoryAction },
{ 0x19, PacketTypesOut.UpdateSign },
{ 0x1A, PacketTypesOut.Animation },
{ 0x1B, PacketTypesOut.Spectate },
{ 0x1C, PacketTypesOut.PlayerBlockPlacement },
{ 0x1D, PacketTypesOut.UseItem },
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => new();
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => new();
}
}

View file

@ -0,0 +1,266 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes;
public class PacketPalette261 : PacketTypePalette
{
private readonly Dictionary<int, PacketTypesIn> typeIn = new()
{
{ 0x00, PacketTypesIn.Bundle }, // Bundle delimiter
{ 0x01, PacketTypesIn.SpawnEntity }, // Add Entity
{ 0x02, PacketTypesIn.EntityAnimation }, // Animate
{ 0x03, PacketTypesIn.Statistics }, // Award Stats
{ 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack
{ 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction
{ 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data
{ 0x07, PacketTypesIn.BlockAction }, // Block Event
{ 0x08, PacketTypesIn.BlockChange }, // Block Update
{ 0x09, PacketTypesIn.BossBar }, // Boss Event
{ 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty
{ 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished
{ 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start
{ 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes
{ 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles
{ 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions
{ 0x10, PacketTypesIn.DeclareCommands }, // Commands
{ 0x11, PacketTypesIn.CloseWindow }, // Container Close
{ 0x12, PacketTypesIn.WindowItems }, // Container Set Content
{ 0x13, PacketTypesIn.WindowProperty }, // Container Set Data
{ 0x14, PacketTypesIn.SetSlot }, // Container Set Slot
{ 0x15, PacketTypesIn.CookieRequest }, // Cookie Request
{ 0x16, PacketTypesIn.SetCooldown }, // Cooldown
{ 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions
{ 0x18, PacketTypesIn.PluginMessage }, // Custom Payload
{ 0x19, PacketTypesIn.DamageEvent }, // Damage Event
{ 0x1A, PacketTypesIn.DebugBlockValue }, // Debug Block Value
{ 0x1B, PacketTypesIn.DebugChunkValue }, // Debug Chunk Value
{ 0x1C, PacketTypesIn.DebugEntityValue }, // Debug Entity Value
{ 0x1D, PacketTypesIn.DebugEvent }, // Debug Event
{ 0x1E, PacketTypesIn.DebugSample }, // Debug Sample
{ 0x1F, PacketTypesIn.HideMessage }, // Delete Chat
{ 0x20, PacketTypesIn.Disconnect }, // Disconnect
{ 0x21, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat
{ 0x22, PacketTypesIn.EntityStatus }, // Entity Event
{ 0x23, PacketTypesIn.EntityPositionSync }, // Entity Position Sync
{ 0x24, PacketTypesIn.Explosion }, // Explode
{ 0x25, PacketTypesIn.UnloadChunk }, // Forget Level Chunk
{ 0x26, PacketTypesIn.ChangeGameState }, // Game Event
{ 0x27, PacketTypesIn.GameRuleValues }, // Game Rule Values (new in 26.1)
{ 0x28, PacketTypesIn.GameTestHighlightPos }, // Game Test Highlight Pos
{ 0x29, PacketTypesIn.OpenHorseWindow }, // Mount Screen Open (renamed from Horse Screen Open)
{ 0x2A, PacketTypesIn.HurtAnimation }, // Hurt Animation
{ 0x2B, PacketTypesIn.InitializeWorldBorder }, // Initialize Border
{ 0x2C, PacketTypesIn.KeepAlive }, // Keep Alive
{ 0x2D, PacketTypesIn.ChunkData }, // Level Chunk With Light
{ 0x2E, PacketTypesIn.Effect }, // Level Event
{ 0x2F, PacketTypesIn.Particle }, // Level Particles
{ 0x30, PacketTypesIn.UpdateLight }, // Light Update
{ 0x31, PacketTypesIn.JoinGame }, // Login
{ 0x32, PacketTypesIn.LowDiskSpaceWarning }, // Low Disk Space Warning (new in 26.1)
{ 0x33, PacketTypesIn.MapData }, // Map Item Data
{ 0x34, PacketTypesIn.TradeList }, // Merchant Offers
{ 0x35, PacketTypesIn.EntityPosition }, // Move Entity Pos
{ 0x36, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot
{ 0x37, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track
{ 0x38, PacketTypesIn.EntityRotation }, // Move Entity Rot
{ 0x39, PacketTypesIn.VehicleMove }, // Move Vehicle
{ 0x3A, PacketTypesIn.OpenBook }, // Open Book
{ 0x3B, PacketTypesIn.OpenWindow }, // Open Screen
{ 0x3C, PacketTypesIn.OpenSignEditor }, // Open Sign Editor
{ 0x3D, PacketTypesIn.Ping }, // Ping
{ 0x3E, PacketTypesIn.PingResponse }, // Pong Response
{ 0x3F, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe
{ 0x40, PacketTypesIn.PlayerAbilities }, // Player Abilities
{ 0x41, PacketTypesIn.ChatMessage }, // Player Chat
{ 0x42, PacketTypesIn.EndCombatEvent }, // Player Combat End
{ 0x43, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter
{ 0x44, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill
{ 0x45, PacketTypesIn.PlayerRemove }, // Player Info Remove
{ 0x46, PacketTypesIn.PlayerInfo }, // Player Info Update
{ 0x47, PacketTypesIn.FacePlayer }, // Player Look At
{ 0x48, PacketTypesIn.PlayerPositionAndLook }, // Player Position
{ 0x49, PacketTypesIn.PlayerRotation }, // Player Rotation
{ 0x4A, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add
{ 0x4B, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove
{ 0x4C, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings
{ 0x4D, PacketTypesIn.DestroyEntities }, // Remove Entities
{ 0x4E, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect
{ 0x4F, PacketTypesIn.ResetScore }, // Reset Score
{ 0x50, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop
{ 0x51, PacketTypesIn.ResourcePackSend }, // Resource Pack Push
{ 0x52, PacketTypesIn.Respawn }, // Respawn
{ 0x53, PacketTypesIn.EntityHeadLook }, // Rotate Head
{ 0x54, PacketTypesIn.MultiBlockChange }, // Section Blocks Update
{ 0x55, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab
{ 0x56, PacketTypesIn.ServerData }, // Server Data
{ 0x57, PacketTypesIn.ActionBar }, // Set Action Bar Text
{ 0x58, PacketTypesIn.WorldBorderCenter }, // Set Border Center
{ 0x59, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size
{ 0x5A, PacketTypesIn.WorldBorderSize }, // Set Border Size
{ 0x5B, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay
{ 0x5C, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance
{ 0x5D, PacketTypesIn.Camera }, // Set Camera
{ 0x5E, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center
{ 0x5F, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius
{ 0x60, PacketTypesIn.SetCursorItem }, // Set Cursor Item
{ 0x61, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position
{ 0x62, PacketTypesIn.DisplayScoreboard }, // Set Display Objective
{ 0x63, PacketTypesIn.EntityMetadata }, // Set Entity Data
{ 0x64, PacketTypesIn.AttachEntity }, // Set Entity Link
{ 0x65, PacketTypesIn.EntityVelocity }, // Set Entity Motion
{ 0x66, PacketTypesIn.EntityEquipment }, // Set Equipment
{ 0x67, PacketTypesIn.SetExperience }, // Set Experience
{ 0x68, PacketTypesIn.UpdateHealth }, // Set Health
{ 0x69, PacketTypesIn.SetHeldSlot }, // Set Held Slot
{ 0x6A, PacketTypesIn.ScoreboardObjective }, // Set Objective
{ 0x6B, PacketTypesIn.SetPassengers }, // Set Passengers
{ 0x6C, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory
{ 0x6D, PacketTypesIn.Teams }, // Set Player Team
{ 0x6E, PacketTypesIn.UpdateScore }, // Set Score
{ 0x6F, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance
{ 0x70, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text
{ 0x71, PacketTypesIn.TimeUpdate }, // Set Time
{ 0x72, PacketTypesIn.SetTitleText }, // Set Title Text
{ 0x73, PacketTypesIn.SetTitleTime }, // Set Titles Animation
{ 0x74, PacketTypesIn.EntitySoundEffect }, // Sound Entity
{ 0x75, PacketTypesIn.SoundEffect }, // Sound
{ 0x76, PacketTypesIn.StartConfiguration }, // Start Configuration
{ 0x77, PacketTypesIn.StopSound }, // Stop Sound
{ 0x78, PacketTypesIn.StoreCookie }, // Store Cookie
{ 0x79, PacketTypesIn.SystemChat }, // System Chat
{ 0x7A, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List
{ 0x7B, PacketTypesIn.NBTQueryResponse }, // Tag Query
{ 0x7C, PacketTypesIn.CollectItem }, // Take Item Entity
{ 0x7D, PacketTypesIn.EntityTeleport }, // Teleport Entity
{ 0x7E, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status
{ 0x7F, PacketTypesIn.SetTickingState }, // Ticking State
{ 0x80, PacketTypesIn.StepTick }, // Ticking Step
{ 0x81, PacketTypesIn.Transfer }, // Transfer
{ 0x82, PacketTypesIn.Advancements }, // Update Advancements
{ 0x83, PacketTypesIn.EntityProperties }, // Update Attributes
{ 0x84, PacketTypesIn.EntityEffect }, // Update Mob Effect
{ 0x85, PacketTypesIn.DeclareRecipes }, // Update Recipes
{ 0x86, PacketTypesIn.Tags }, // Update Tags
{ 0x87, PacketTypesIn.ProjectilePower }, // Projectile Power
{ 0x88, PacketTypesIn.CustomReportDetails }, // Custom Report Details
{ 0x89, PacketTypesIn.ServerLinks }, // Server Links
{ 0x8A, PacketTypesIn.Waypoint }, // Waypoint
{ 0x8B, PacketTypesIn.ClearDialog }, // Clear Dialog
{ 0x8C, PacketTypesIn.ShowDialog } // Show Dialog
};
private readonly Dictionary<int, PacketTypesOut> typeOut = new()
{
{ 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation
{ 0x01, PacketTypesOut.Attack }, // Attack (new in 26.1)
{ 0x02, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query
{ 0x03, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected
{ 0x04, PacketTypesOut.SetDifficulty }, // Change Difficulty
{ 0x05, PacketTypesOut.ChangeGameMode }, // Change Game Mode
{ 0x06, PacketTypesOut.MessageAcknowledgment }, // Chat Ack
{ 0x07, PacketTypesOut.ChatCommand }, // Chat Command
{ 0x08, PacketTypesOut.SignedChatCommand }, // Chat Command Signed
{ 0x09, PacketTypesOut.ChatMessage }, // Chat
{ 0x0A, PacketTypesOut.PlayerSession }, // Chat Session Update
{ 0x0B, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received
{ 0x0C, PacketTypesOut.ClientStatus }, // Client Command
{ 0x0D, PacketTypesOut.ClientTickEnd }, // Client Tick End
{ 0x0E, PacketTypesOut.ClientSettings }, // Client Information
{ 0x0F, PacketTypesOut.TabComplete }, // Command Suggestion
{ 0x10, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged
{ 0x11, PacketTypesOut.ClickWindowButton }, // Container Button Click
{ 0x12, PacketTypesOut.ClickWindow }, // Container Click
{ 0x13, PacketTypesOut.CloseWindow }, // Container Close
{ 0x14, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed
{ 0x15, PacketTypesOut.CookieResponse }, // Cookie Response
{ 0x16, PacketTypesOut.PluginMessage }, // Custom Payload
{ 0x17, PacketTypesOut.DebugSampleSubscription }, // Debug Subscription Request (renamed)
{ 0x18, PacketTypesOut.EditBook }, // Edit Book
{ 0x19, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query
{ 0x1A, PacketTypesOut.InteractEntity }, // Interact
{ 0x1B, PacketTypesOut.GenerateStructure }, // Jigsaw Generate
{ 0x1C, PacketTypesOut.KeepAlive }, // Keep Alive
{ 0x1D, PacketTypesOut.LockDifficulty }, // Lock Difficulty
{ 0x1E, PacketTypesOut.PlayerPosition }, // Move Player Pos
{ 0x1F, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot
{ 0x20, PacketTypesOut.PlayerRotation }, // Move Player Rot
{ 0x21, PacketTypesOut.PlayerMovement }, // Move Player Status Only
{ 0x22, PacketTypesOut.VehicleMove }, // Move Vehicle
{ 0x23, PacketTypesOut.SteerBoat }, // Paddle Boat
{ 0x24, PacketTypesOut.PickItem }, // Pick Item From Block
{ 0x25, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity
{ 0x26, PacketTypesOut.PingRequest }, // Ping Request
{ 0x27, PacketTypesOut.CraftRecipeRequest }, // Place Recipe
{ 0x28, PacketTypesOut.PlayerAbilities }, // Player Abilities
{ 0x29, PacketTypesOut.PlayerDigging }, // Player Action
{ 0x2A, PacketTypesOut.EntityAction }, // Player Command
{ 0x2B, PacketTypesOut.SteerVehicle }, // Player Input
{ 0x2C, PacketTypesOut.PlayerLoaded }, // Player Loaded
{ 0x2D, PacketTypesOut.Pong }, // Pong
{ 0x2E, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings
{ 0x2F, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe
{ 0x30, PacketTypesOut.NameItem }, // Rename Item
{ 0x31, PacketTypesOut.ResourcePackStatus }, // Resource Pack
{ 0x32, PacketTypesOut.AdvancementTab }, // Seen Advancements
{ 0x33, PacketTypesOut.SelectTrade }, // Select Trade
{ 0x34, PacketTypesOut.SetBeaconEffect }, // Set Beacon
{ 0x35, PacketTypesOut.HeldItemChange }, // Set Carried Item
{ 0x36, PacketTypesOut.UpdateCommandBlock }, // Set Command Block
{ 0x37, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart
{ 0x38, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot
{ 0x39, PacketTypesOut.SetGameRule }, // Set Game Rule (new in 26.1)
{ 0x3A, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block
{ 0x3B, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block
{ 0x3C, PacketTypesOut.SetTestBlock }, // Set Test Block
{ 0x3D, PacketTypesOut.UpdateSign }, // Sign Update
{ 0x3F, PacketTypesOut.Animation }, // Swing
{ 0x40, PacketTypesOut.Spectate }, // Teleport To Entity
{ 0x41, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action
{ 0x42, PacketTypesOut.PlayerBlockPlacement }, // Use Item On
{ 0x43, PacketTypesOut.UseItem }, // Use Item
{ 0x44, PacketTypesOut.CustomClickAction } // Custom Click Action
};
private readonly Dictionary<int, ConfigurationPacketTypesIn> configurationTypesIn = new()
{
{ 0x00, ConfigurationPacketTypesIn.CookieRequest },
{ 0x01, ConfigurationPacketTypesIn.PluginMessage },
{ 0x02, ConfigurationPacketTypesIn.Disconnect },
{ 0x03, ConfigurationPacketTypesIn.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesIn.KeepAlive },
{ 0x05, ConfigurationPacketTypesIn.Ping },
{ 0x06, ConfigurationPacketTypesIn.ResetChat },
{ 0x07, ConfigurationPacketTypesIn.RegistryData },
{ 0x08, ConfigurationPacketTypesIn.RemoveResourcePack },
{ 0x09, ConfigurationPacketTypesIn.ResourcePack },
{ 0x0A, ConfigurationPacketTypesIn.StoreCookie },
{ 0x0B, ConfigurationPacketTypesIn.Transfer },
{ 0x0C, ConfigurationPacketTypesIn.FeatureFlags },
{ 0x0D, ConfigurationPacketTypesIn.UpdateTags },
{ 0x0E, ConfigurationPacketTypesIn.KnownDataPacks },
{ 0x0F, ConfigurationPacketTypesIn.CustomReportDetails },
{ 0x10, ConfigurationPacketTypesIn.ServerLinks },
{ 0x11, ConfigurationPacketTypesIn.ClearDialog },
{ 0x12, ConfigurationPacketTypesIn.ShowDialog },
{ 0x13, ConfigurationPacketTypesIn.CodeOfConduct }
};
private readonly Dictionary<int, ConfigurationPacketTypesOut> configurationTypesOut = new()
{
{ 0x00, ConfigurationPacketTypesOut.ClientInformation },
{ 0x01, ConfigurationPacketTypesOut.CookieResponse },
{ 0x02, ConfigurationPacketTypesOut.PluginMessage },
{ 0x03, ConfigurationPacketTypesOut.FinishConfiguration },
{ 0x04, ConfigurationPacketTypesOut.KeepAlive },
{ 0x05, ConfigurationPacketTypesOut.Pong },
{ 0x06, ConfigurationPacketTypesOut.ResourcePackResponse },
{ 0x07, ConfigurationPacketTypesOut.KnownDataPacks },
{ 0x08, ConfigurationPacketTypesOut.CustomClickAction },
{ 0x09, ConfigurationPacketTypesOut.AcceptCodeOfConduct }
};
protected override Dictionary<int, PacketTypesIn> GetListIn() => typeIn;
protected override Dictionary<int, PacketTypesOut> GetListOut() => typeOut;
protected override Dictionary<int, ConfigurationPacketTypesIn> GetConfigurationListIn() => configurationTypesIn!;
protected override Dictionary<int, ConfigurationPacketTypesOut> GetConfigurationListOut() => configurationTypesOut!;
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using MinecraftClient.Protocol.Handlers.PacketPalettes;
namespace MinecraftClient.Protocol.Handlers
@ -48,9 +48,15 @@ namespace MinecraftClient.Protocol.Handlers
{
PacketTypePalette p = protocol switch
{
> Protocol18Handler.MC_1_20_4_Version => throw new NotImplementedException(Translations
> Protocol18Handler.MC_26_1_Version => throw new NotImplementedException(Translations
.exception_palette_packet),
>= Protocol18Handler.MC_26_1_Version => new PacketPalette261(),
<= Protocol18Handler.MC_1_21_11_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(),
<= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(),
<= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(),
<= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(),
<= Protocol18Handler.MC_1_8_Version => new PacketPalette17(),
<= Protocol18Handler.MC_1_9_2_Version => new PacketPalette19(),
<= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(),
<= Protocol18Handler.MC_1_12_Version => new PacketPalette112(),
<= Protocol18Handler.MC_1_12_2_Version => new PacketPalette1122(),
@ -67,7 +73,10 @@ namespace MinecraftClient.Protocol.Handlers
<= Protocol18Handler.MC_1_19_4_Version => new PacketPalette1194(),
<= Protocol18Handler.MC_1_20_Version => new PacketPalette1194(),
<= Protocol18Handler.MC_1_20_2_Version => new PacketPalette1202(),
_ => new PacketPalette1204()
<= Protocol18Handler.MC_1_20_4_Version => new PacketPalette1204(),
<= Protocol18Handler.MC_1_20_6_Version => new PacketPalette1206(),
<= Protocol18Handler.MC_1_21_Version => new PacketPalette121(),
_ => new PacketPalette1212()
};
p.SetForgeEnabled(forgeEnabled);

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Protocol.Handlers
namespace MinecraftClient.Protocol.Handlers
{
/// <summary>
/// Incoming packet types
@ -29,9 +29,12 @@
CloseWindow, //
CollectItem, //
CombatEvent, //
CookieRequest, // Added in 1.20.6
CraftRecipeResponse, //
CustomReportDetails, // Added in 1.21 (Not used)
DamageEvent, // Added in 1.19.4
DeathCombatEvent, //
DebugSample, // Added in 1.20.6
DeclareCommands, //
DeclareRecipes, //
DestroyEntities, //
@ -48,6 +51,7 @@
EntityMovement, //
EntityPosition, //
EntityPositionAndRotation, //
EntityPositionSync, // Added in 1.21.2
EntityProperties, //
EntityRotation, //
EntitySoundEffect, //
@ -55,6 +59,7 @@
EntityTeleport, //
EntityVelocity, //
Explosion, //
MoveMinecartAlongTrack, // Added in 1.21.2
FacePlayer, //
FeatureFlags, // Added in 1.19.3
HeldItemChange, //
@ -81,22 +86,31 @@
PlayerListHeaderAndFooter, //
PlayerRemove, // Added in 1.19.3 (Not used)
PlayerPositionAndLook, //
PlayerRotation, // Added in 1.21.2
PluginMessage, //
ProfilelessChatMessage, // Added in 1.19.3
ProjectilePower, // Added in 1.20.6
RemoveEntityEffect, //
RemoveResourcePack, // Added in 1.20.3
ResetScore, // Added in 1.20.3
ResourcePackSend, //
Respawn, //
RecipeBookAdd, // Added in 1.21.2 (replaces UnlockRecipes)
RecipeBookRemove, // Added in 1.21.2
RecipeBookSettings, // Added in 1.21.2
ScoreboardObjective, //
SelectAdvancementTab, //
ServerData, // Added in 1.19
ServerDifficulty, //
ServerLinks, // Added in 1.21 (Not used)
SetCompression, // For 1.8 or below
SetCooldown, //
SetCursorItem, // Added in 1.21.2
SetDisplayChatPreview, // Added in 1.19
SetExperience, //
SetHeldSlot, // Added in 1.21.2 (replaces HeldItemChange clientbound)
SetPassengers, //
SetPlayerInventory, // Added in 1.21.2
SetSlot, //
SetTickingState, // Added in 1.20.3
StepTick, // Added in 1.20.3
@ -115,13 +129,16 @@
StartConfiguration, // Added in 1.20.2
Statistics, //
StopSound, //
StoreCookie, // Added in 1.20.6
SystemChat, // Added in 1.19
TabComplete, //
Tags, //
Teams, //
TestInstanceBlockStatus, // Added in 1.21.5
TimeUpdate, //
Title, //
TradeList, //
Transfer, // Added in 1.20.6
Unknown, // For old version packet that have been removed and not used by mcc
UnloadChunk, //
UnlockRecipes, //
@ -129,7 +146,7 @@
UpdateHealth, //
UpdateLight, //
UpdateScore, //
UpdateSign, // For 1.8 or below
UpdateSign, // For 1.8 or below, and 1.9-1.9.2
UpdateSimulationDistance, //
UpdateViewDistance, //
UpdateViewPosition, //
@ -144,5 +161,15 @@
WorldBorderSize, //
WorldBorderWarningDelay, //
WorldBorderWarningReach, //
Waypoint, // Added in 1.21.6
ClearDialog, // Added in 1.21.6
ShowDialog, // Added in 1.21.6
DebugBlockValue, // Added in 1.21.9
DebugChunkValue, // Added in 1.21.9
DebugEntityValue, // Added in 1.21.9
DebugEvent, // Added in 1.21.9
GameTestHighlightPos, // Added in 1.21.9
GameRuleValues, // Added in 26.1
LowDiskSpaceWarning, // Added in 26.1
}
}

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Protocol.Handlers
namespace MinecraftClient.Protocol.Handlers
{
/// <summary>
/// Outgoing packet types
@ -8,6 +8,7 @@
AcknowledgeConfiguration, // Added in 1.20.2
AdvancementTab, //
Animation, //
BundleItemSelected, // Added in 1.21.2
ChangeContainerSlotState, // Added in 1.20.3
ChatCommand, // Added in 1.19
ChatMessage, //
@ -17,9 +18,12 @@
ClickWindowButton, //
ClientSettings, //
ClientStatus, //
ClientTickEnd, // Added in 1.21.2
CloseWindow, //
CraftRecipeRequest, //
CreativeInventoryAction, //
CookieResponse, // Added in 1.20.6
DebugSampleSubscription, // Added in 1.20.6
EditBook, //
EnchantItem, // For 1.13.2 or below
EntityAction, //
@ -28,14 +32,17 @@
HeldItemChange, //
InteractEntity, //
KeepAlive, //
KnownDataPacks, // Added in 1.20.6
LockDifficulty, //
MessageAcknowledgment, // Added in 1.19.1 (1.19.2)
NameItem, //
PickItem, //
PickItemFromEntity, // Added in 1.21.4 (split from PickItem)
PingRequest, // Added in 1.20.2
PlayerAbilities, //
PlayerBlockPlacement, //
PlayerDigging, //
PlayerLoaded, // Added in 1.21.4
PlayerMovement, //
PlayerPosition, //
PlayerPositionAndRotation, //
@ -52,6 +59,7 @@
SetDifficulty, //
SetDisplayedRecipe, // Added in 1.16.2
SetRecipeBookState, // Added in 1.16.2
SignedChatCommand, // Added in 1.20.6
Spectate, //
SteerBoat, //
SteerVehicle, //
@ -63,8 +71,14 @@
UpdateJigsawBlock, //
UpdateSign, //
UpdateStructureBlock, //
SetTestBlock, // Added in 1.21.5
TestInstanceBlockAction, // Added in 1.21.5
UseItem, //
VehicleMove, //
WindowConfirmation, //
ChangeGameMode, // Added in 1.21.6
CustomClickAction, // Added in 1.21.6
Attack, // Added in 26.1
SetGameRule, // Added in 26.1
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net.Sockets;
@ -70,24 +71,41 @@ namespace MinecraftClient.Protocol.Handlers
private void Updater(object? o)
{
if (((CancellationToken)o!).IsCancellationRequested)
var cancelToken = (CancellationToken)o!;
if (cancelToken.IsCancellationRequested)
return;
try
{
while (!((CancellationToken)o!).IsCancellationRequested)
Stopwatch stopWatch = Stopwatch.StartNew();
long nextUpdateDue = 0;
while (!cancelToken.IsCancellationRequested)
{
do
cancelToken.ThrowIfCancellationRequested();
long elapsedMilliseconds = stopWatch.ElapsedMilliseconds;
while (elapsedMilliseconds >= nextUpdateDue)
{
Thread.Sleep(100);
} while (Update());
if (!Update())
return;
nextUpdateDue += ClientTickIntervalMilliseconds;
elapsedMilliseconds = stopWatch.ElapsedMilliseconds;
}
long sleepLength = nextUpdateDue - stopWatch.ElapsedMilliseconds;
if (sleepLength > 1)
Thread.Sleep((int)Math.Min(sleepLength, ClientTickIntervalMilliseconds));
}
}
catch (System.IO.IOException) { }
catch (SocketException) { }
catch (ObjectDisposedException) { }
catch (OperationCanceledException) { }
if (((CancellationToken)o!).IsCancellationRequested)
if (cancelToken.IsCancellationRequested)
return;
handler.OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, "");
@ -114,6 +132,7 @@ namespace MinecraftClient.Protocol.Handlers
byte[] keepalive = new byte[5] { 0, 0, 0, 0, 0 };
Receive(keepalive, 1, 4, SocketFlags.None);
handler.OnServerKeepAlive();
handler.SetCanSendMessage(true);
Send(keepalive); break;
case 0x01: ReadData(4); ReadNextString(); ReadData(5); break;
case 0x02: ReadData(1); ReadNextString(); ReadNextString(); ReadData(4); break;
@ -190,7 +209,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0xC9:
string name = ReadNextString(); bool online = ReadNextByte() != 0x00; ReadData(2);
Guid FakeUUID = new(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray());
if (online) { handler.OnPlayerJoin(new PlayerInfo(name, FakeUUID)); } else { handler.OnPlayerLeave(FakeUUID); }
if (online) handler.OnPlayerJoin(new PlayerInfo(name, FakeUUID));
else handler.OnPlayerLeave(FakeUUID);
break;
case 0xCA: if (protocolversion >= 72) { ReadData(9); } else ReadData(3); break;
case 0xCB:
@ -233,14 +253,29 @@ namespace MinecraftClient.Protocol.Handlers
/// <returns>Net read thread ID</returns>
public int GetNetMainThreadId()
{
return netRead != null ? netRead.Item1.ManagedThreadId : -1;
return netRead is not null ? netRead.Item1.ManagedThreadId : -1;
}
public bool SendCookieResponse(string name, byte[]? data)
{
throw new NotImplementedException();
}
public bool SendKnownDataPacks(List<(string, string, string)> knownDataPacks)
{
throw new NotImplementedException();
}
public bool SendCustomClickAction(string id, Dictionary<string, object>? payload)
{
return false;
}
public void Dispose()
{
try
{
if (netRead != null)
if (netRead is not null)
{
netRead.Item2.Cancel();
c.Close();
@ -522,13 +557,13 @@ namespace MinecraftClient.Protocol.Handlers
if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted("§8" + Translations.debug_crypto, acceptnewlines: true);
if (serverIDhash != "-")
if (serverIDhash != "-" && !string.IsNullOrWhiteSpace(sessionID))
{
ConsoleIO.WriteLine(Translations.mcc_session);
string serverHash = CryptoHandler.GetServerHash(serverIDhash, serverPublicKey, secretKey);
bool needCheckSession = true;
if (session.ServerPublicKey != null && session.SessionPreCheckTask != null
if (session.ServerPublicKey is not null && session.SessionPreCheckTask is not null
&& serverIDhash == session.ServerIDhash && Enumerable.SequenceEqual(serverPublicKey, session.ServerPublicKey))
{
session.SessionPreCheckTask.Wait();
@ -590,7 +625,7 @@ namespace MinecraftClient.Protocol.Handlers
}
}
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session)
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session, bool isTransfer = false)
{
if (Handshake(handler.GetUserUuidStr(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort(), session))
{
@ -668,7 +703,8 @@ namespace MinecraftClient.Protocol.Handlers
public int GetMaxChatMessageLength()
{
return 100;
int configOverride = Settings.MainConfigHelper.Config.Advanced.MaxChatMessageLength;
return configOverride > 0 ? configOverride : 100;
}
public int GetProtocolVersion()
@ -727,7 +763,7 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented
}
public bool SendLocationUpdate(Location location, bool onGround, float? yaw, float? pitch)
public bool SendLocationUpdate(Location location, bool onGround, bool horizontalCollision, float? yaw, float? pitch)
{
return false; //Currently not implemented
}
@ -782,6 +818,16 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented
}
public bool SendPlaceRecipe(int windowId, string recipeId, bool makeAll)
{
return false; //MC 1.8-1.12.1 recipe book not supported
}
public bool SendEditBook(Item currentBook, IReadOnlyList<string> pages, string? title, string author, int selectedHotbarSlot)
{
return false; //MC 1.4.6-1.6.4 book editing is not supported
}
public bool SendCloseWindow(int windowId)
{
return false; //Currently not implemented
@ -910,7 +956,7 @@ namespace MinecraftClient.Protocol.Handlers
{
return false; //Currently not implemented
}
public bool SendRenameItem(string itemName)
{
return false;

File diff suppressed because it is too large Load diff

View file

@ -12,31 +12,16 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Handler for the Minecraft Forge protocol
/// </summary>
class Protocol18Forge
class Protocol18Forge(ForgeInfo? forgeInfo, int protocolVersion, DataTypes dataTypes, Protocol18Handler protocol18, IMinecraftComHandler mcHandler)
{
private readonly int protocolversion;
private readonly DataTypes dataTypes;
private readonly Protocol18Handler protocol18;
private readonly IMinecraftComHandler mcHandler;
private readonly int protocolversion = protocolVersion;
private readonly DataTypes dataTypes = dataTypes;
private readonly Protocol18Handler protocol18 = protocol18;
private readonly IMinecraftComHandler mcHandler = mcHandler;
private readonly ForgeInfo? forgeInfo;
private readonly ForgeInfo? forgeInfo = forgeInfo;
private FMLHandshakeClientState fmlHandshakeState = FMLHandshakeClientState.START;
private bool ForgeEnabled() { return forgeInfo != null; }
/// <summary>
/// Initialize a new Forge protocol handler
/// </summary>
/// <param name="forgeInfo">Forge Server Information</param>
/// <param name="protocolVersion">Minecraft protocol version</param>
/// <param name="dataTypes">Minecraft data types handler</param>
public Protocol18Forge(ForgeInfo? forgeInfo, int protocolVersion, DataTypes dataTypes, Protocol18Handler protocol18, IMinecraftComHandler mcHandler)
{
this.forgeInfo = forgeInfo;
protocolversion = protocolVersion;
this.dataTypes = dataTypes;
this.protocol18 = protocol18;
this.mcHandler = mcHandler;
}
private bool ForgeEnabled() { return forgeInfo is not null; }
/// <summary>
/// Get Forge-Tagged server address
@ -316,6 +301,8 @@ namespace MinecraftClient.Protocol.Handlers
for (int i = 0; i < modCount; i++)
mods.Add(dataTypes.ReadNextString(packetData));
ChatParser.LoadForgeModTranslations(mods);
Dictionary<string, string> channels = new();
int channelCount = dataTypes.ReadNextVarInt(packetData);
for (int i = 0; i < channelCount; i++)
@ -390,7 +377,7 @@ namespace MinecraftClient.Protocol.Handlers
string registryName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_registry, registryName));
}
fmlResponsePacket.AddRange(DataTypes.GetVarInt(99));
fmlResponseReady = true;
break;
@ -423,7 +410,7 @@ namespace MinecraftClient.Protocol.Handlers
// [ Version ][ String ]
//
// We're ignoring this packet in MCC
if (Settings.Config.Logging.DebugMessages)
{
ConsoleIO.WriteLineFormatted("§8" + "Received FML3 Server Mod Data List");
@ -484,7 +471,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="jsonData">JSON data returned by the server</param>
/// <param name="forgeInfo">ForgeInfo to populate</param>
/// <returns>True if the server is running Forge</returns>
public static bool ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo? forgeInfo)
public static bool ServerInfoCheckForge(System.Text.Json.Nodes.JsonObject jsonData, ref ForgeInfo? forgeInfo)
{
return ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML) // MC 1.12 and lower
|| ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML2) // MC 1.13 to 1.17
@ -518,7 +505,7 @@ namespace MinecraftClient.Protocol.Handlers
{
return new ForgeInfo(FMLVersion.FML3);
}
return new ForgeInfo(FMLVersion.FML2);
return new ForgeInfo(FMLVersion.FML2);
}
else throw new InvalidOperationException(Translations.error_forgeforce);
}
@ -530,7 +517,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="forgeInfo">ForgeInfo to populate</param>
/// <param name="fmlVersion">Forge protocol version</param>
/// <returns>True if the server is running Forge</returns>
private static bool ServerInfoCheckForgeSub(Json.JSONData jsonData, ref ForgeInfo? forgeInfo, FMLVersion fmlVersion)
private static bool ServerInfoCheckForgeSub(System.Text.Json.Nodes.JsonObject jsonData, ref ForgeInfo? forgeInfo, FMLVersion fmlVersion)
{
string forgeDataTag;
string versionField;
@ -557,10 +544,9 @@ namespace MinecraftClient.Protocol.Handlers
throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!");
}
if (jsonData.Properties.ContainsKey(forgeDataTag) && jsonData.Properties[forgeDataTag].Type == Json.JSONData.DataType.Object)
if (jsonData[forgeDataTag] is System.Text.Json.Nodes.JsonObject modData)
{
Json.JSONData modData = jsonData.Properties[forgeDataTag];
if (modData.Properties.ContainsKey(versionField) && modData.Properties[versionField].StringValue == versionString)
if (modData[versionField] is not null && modData[versionField]!.GetStringValue() == versionString)
{
forgeInfo = new ForgeInfo(modData, fmlVersion);
if (forgeInfo.Mods.Any())
@ -582,6 +568,6 @@ namespace MinecraftClient.Protocol.Handlers
}
}
return false;
}
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -12,23 +12,11 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Terrain Decoding handler for Protocol18
/// </summary>
class Protocol18Terrain
class Protocol18Terrain(int protocolVersion, DataTypes dataTypes, IMinecraftComHandler handler)
{
private readonly int protocolversion;
private readonly DataTypes dataTypes;
private readonly IMinecraftComHandler handler;
/// <summary>
/// Initialize a new Terrain Decoder
/// </summary>
/// <param name="protocolVersion">Minecraft Protocol Version</param>
/// <param name="dataTypes">Minecraft Protocol Data Types</param>
public Protocol18Terrain(int protocolVersion, DataTypes dataTypes, IMinecraftComHandler handler)
{
protocolversion = protocolVersion;
this.dataTypes = dataTypes;
this.handler = handler;
}
private readonly int protocolversion = protocolVersion;
private readonly DataTypes dataTypes = dataTypes;
private readonly IMinecraftComHandler handler = handler;
/// <summary>
/// Reading the "Block states" field: consists of 4096 entries, representing all the blocks in the chunk section.
@ -47,7 +35,8 @@ namespace MinecraftClient.Protocol.Handlers
ushort blockId = (ushort)dataTypes.ReadNextVarInt(cache);
Block block = new(blockId);
dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero
if (protocolversion < Protocol18Handler.MC_1_21_5_Version)
dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero (removed in 1.21.5)
// Empty chunks will not be stored
if (block.Type == Material.Air)
@ -80,7 +69,8 @@ namespace MinecraftClient.Protocol.Handlers
palette[i] = (uint)dataTypes.ReadNextVarInt(cache);
//// Block IDs are packed in the array of 64-bits integers
dataTypes.SkipNextVarInt(cache); // Entry length
if (protocolversion < Protocol18Handler.MC_1_21_5_Version)
dataTypes.SkipNextVarInt(cache); // Entry length (removed in 1.21.5)
Span<byte> entryDataByte = stackalloc byte[8];
Span<long> entryDataLong = MemoryMarshal.Cast<byte, long>(entryDataByte); // Faster than MemoryMarshal.Read<long>
@ -183,6 +173,9 @@ namespace MinecraftClient.Protocol.Handlers
// Non-air block count inside chunk section, for lighting purposes
int blockCnt = dataTypes.ReadNextShort(cache);
if (protocolversion >= Protocol18Handler.MC_26_1_Version)
dataTypes.ReadNextShort(cache); // Fluid count (26.1+)
// Read Block states (Type: Paletted Container)
Chunk? chunk = ReadBlockStatesField(cache);
@ -196,8 +189,8 @@ namespace MinecraftClient.Protocol.Handlers
if (bitsPerEntryBiome == 0)
{
dataTypes.SkipNextVarInt(cache); // Value
dataTypes.SkipNextVarInt(cache); // Data Array Length
// Data Array must be empty
if (protocolversion < Protocol18Handler.MC_1_21_5_Version)
dataTypes.SkipNextVarInt(cache); // Data Array Length (removed in 1.21.5)
}
else
{
@ -207,8 +200,20 @@ namespace MinecraftClient.Protocol.Handlers
for (int i = 0; i < paletteLength; i++)
dataTypes.SkipNextVarInt(cache); // Palette
}
int dataArrayLength = dataTypes.ReadNextVarInt(cache); // Data Array Length
dataTypes.DropData(dataArrayLength * 8, cache); // Data Array
if (protocolversion >= Protocol18Handler.MC_1_21_5_Version)
{
// 1.21.5: No VarInt length prefix; calculate from bits per entry
// Biome container has 64 entries (4x4x4)
// Uses SimpleBitStorage: valuesPerLong = 64/bitsPerEntry, longs = ceil(64/valuesPerLong)
int valuesPerLong = 64 / bitsPerEntryBiome;
int dataArrayLength = (64 + valuesPerLong - 1) / valuesPerLong;
dataTypes.DropData(dataArrayLength * 8, cache);
}
else
{
int dataArrayLength = dataTypes.ReadNextVarInt(cache); // Data Array Length
dataTypes.DropData(dataArrayLength * 8, cache); // Data Array
}
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.Sockets;
using MinecraftClient.Crypto;
@ -7,7 +7,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Wrapper for handling unencrypted & encrypted socket
/// </summary>
class SocketWrapper
public class SocketWrapper
{
readonly TcpClient c;
AesCfb8Stream? s;
@ -29,7 +29,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <remarks>Silently dropped connection can only be detected by attempting to read/write data</remarks>
public bool IsConnected()
{
return c.Client != null && c.Connected;
return c.Client is not null && c.Connected;
}
/// <summary>
@ -90,6 +90,9 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="buffer">data to send</param>
public void SendDataRAW(byte[] buffer)
{
if (!IsConnected())
throw new SocketException((int)SocketError.NotConnected);
if (encrypted)
s!.Write(buffer, 0, buffer.Length);
else

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class AttributeModifiersComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfAttributes { get; set; }
public List<SubComponent> Attributes { get; set; } = new();
public bool ShowInTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
NumberOfAttributes = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfAttributes; i++)
Attributes.Add(SubComponentRegistry.ParseSubComponent(SubComponents.Attribute, data));
ShowInTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfAttributes));
if (Attributes.Count != NumberOfAttributes)
throw new ArgumentNullException($"Can not serialize a AttributeModifiersComponent when the Attributes count != NumberOfAttributes!");
foreach (var attribute in Attributes)
data.AddRange(attribute.Serialize());
data.AddRange(DataTypes.GetBool(ShowInTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class BannerPatternsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfLayers { get; set; }
public List<BannerLayer> Layers { get; set; } = [];
public override void Parse(Queue<byte> data)
{
NumberOfLayers = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfLayers; i++)
{
var patternType = DataTypes.ReadNextVarInt(data);
Layers.Add(new BannerLayer
{
PatternType = patternType,
AssetId = patternType == 0 ? DataTypes.ReadNextString(data) : null,
TranslationKey = patternType == 0 ? DataTypes.ReadNextString(data) : null,
DyeColor = DataTypes.ReadNextVarInt(data)
});
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfLayers));
if (NumberOfLayers > 0)
{
if (NumberOfLayers != Layers.Count)
throw new Exception("Can't serialize BannerPatternsComponent because NumberOfLayers and Layers.Count differ!");
foreach (var bannerLayer in Layers)
{
data.AddRange(DataTypes.GetVarInt(bannerLayer.PatternType));
if (bannerLayer.PatternType == 0)
{
if (string.IsNullOrEmpty(bannerLayer.AssetId) || string.IsNullOrEmpty(bannerLayer.TranslationKey))
throw new Exception("Can't serialize BannerPatternsComponent because AssetId or TranslationKey is null/empty!");
data.AddRange(DataTypes.GetString(bannerLayer.AssetId));
data.AddRange(DataTypes.GetString(bannerLayer.TranslationKey));
}
data.AddRange(DataTypes.GetVarInt(bannerLayer.DyeColor));
}
}
return new Queue<byte>(data);
}
}
public record BannerLayer
{
public int PatternType { get; set; }
public string? AssetId { get; set; } = null!;
public string? TranslationKey { get; set; } = null!;
public int DyeColor { get; set; }
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class BaseColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int DyeColor { get; set; }
public override void Parse(Queue<byte> data)
{
DyeColor = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(DyeColor));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class BeesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfBees { get; set; }
public List<Bee> Bees { get; set; } = [];
public override void Parse(Queue<byte> data)
{
NumberOfBees = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfBees; i++)
{
Bees.Add(new Bee(DataTypes.ReadNextNbt(data), DataTypes.ReadNextVarInt(data), DataTypes.ReadNextVarInt(data)));
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfBees));
if (NumberOfBees > 0)
{
if (NumberOfBees != Bees.Count)
throw new Exception("Can't serialize the BeeComponent because NumberOfBees and Bees.Count differ!");
foreach (var bee in Bees)
{
data.AddRange(DataTypes.GetNbt(bee.EntityDataNbt));
data.AddRange(DataTypes.GetVarInt(bee.TicksInHive));
data.AddRange(DataTypes.GetVarInt(bee.MinTicksInHive));
}
}
return new Queue<byte>(data);
}
}
public record Bee(Dictionary<string, object>? EntityDataNbt, int TicksInHive, int MinTicksInHive);

View file

@ -0,0 +1,31 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class BlockStateComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<(string, string)> Properties { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
Properties.Add((DataTypes.ReadNextString(data), DataTypes.ReadNextString(data)));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Properties.Count));
foreach (var (key, value) in Properties)
{
data.AddRange(DataTypes.GetString(key));
data.AddRange(DataTypes.GetString(value));
}
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,35 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class BundleContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<Item> Items { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
{
var item = DataTypes.ReadNextItemSlot(data, ItemPalette);
if (item is not null)
Items.Add(item);
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Items.Count));
foreach (var item in Items)
data.AddRange(DataTypes.GetItemSlot(item, ItemPalette));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CanBreakComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfPredicates { get; set; }
public List<BlockPredicateSubcomponent> BlockPredicates { get; set; } = new();
public bool ShowInTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
NumberOfPredicates = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfPredicates; i++)
BlockPredicates.Add((BlockPredicateSubcomponent)SubComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data));
ShowInTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfPredicates));
if (NumberOfPredicates > 0 && BlockPredicates.Count == 0)
throw new ArgumentNullException($"Can not serialize a CanBreakComponent when the BlockPredicates is empty but NumberOfPredicates is > 0!");
foreach (var blockPredicate in BlockPredicates)
data.AddRange(blockPredicate.Serialize());
data.AddRange(DataTypes.GetBool(ShowInTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CanPlaceOnComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfPredicates { get; set; }
public List<BlockPredicateSubcomponent> BlockPredicates { get; set; } = new();
public bool ShowInTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
NumberOfPredicates = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfPredicates; i++)
BlockPredicates.Add((BlockPredicateSubcomponent)SubComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data));
ShowInTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfPredicates));
if (NumberOfPredicates > 0 && BlockPredicates.Count == 0)
throw new ArgumentNullException($"Can not serialize a CanPlaceOnComponent when the BlockPredicates is empty but NumberOfPredicates is > 0!");
foreach (var blockPredicate in BlockPredicates)
data.AddRange(blockPredicate.Serialize());
data.AddRange(DataTypes.GetBool(ShowInTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,35 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ChargedProjectilesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<Item> Items { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
{
var item = DataTypes.ReadNextItemSlot(data, ItemPalette);
if (item is not null)
Items.Add(item);
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Items.Count));
foreach (var item in Items)
data.AddRange(DataTypes.GetItemSlot(item, ItemPalette));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,29 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ContainerComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<Item?> Items { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
Items.Add(DataTypes.ReadNextItemSlot(data, ItemPalette));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Items.Count));
foreach (var item in Items)
data.AddRange(DataTypes.GetItemSlot(item, ItemPalette));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ContainerLootComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; }
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,8 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CreativeSlotLockComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CustomDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; } = new();
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,52 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CustomModelDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<float> Floats { get; set; } = [];
public List<bool> Flags { get; set; } = [];
public List<string> Strings { get; set; } = [];
public List<int> Colors { get; set; } = [];
public override void Parse(Queue<byte> data)
{
Floats = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextFloat(componentData));
Flags = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextBool(componentData));
Strings = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextString(componentData));
Colors = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextInt(componentData));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
WriteList(data, Floats, static (dataTypes, value) => dataTypes.GetFloat(value));
WriteList(data, Flags, static (dataTypes, value) => dataTypes.GetBool(value));
WriteList(data, Strings, static (dataTypes, value) => dataTypes.GetString(value));
WriteList(data, Colors, static (_, value) => DataTypes.GetInt(value));
return new Queue<byte>(data);
}
private List<T> ReadList<T>(Queue<byte> data, ReadDelegate<T> read)
{
var count = DataTypes.ReadNextVarInt(data);
var values = new List<T>(count);
for (var i = 0; i < count; i++)
values.Add(read(DataTypes, data));
return values;
}
private void WriteList<T>(List<byte> data, List<T> values, WriteDelegate<T> write)
{
data.AddRange(DataTypes.GetVarInt(values.Count));
foreach (var value in values)
data.AddRange(write(DataTypes, value));
}
private delegate T ReadDelegate<out T>(DataTypes dataTypes, Queue<byte> data);
private delegate byte[] WriteDelegate<in T>(DataTypes dataTypes, T value);
}

View file

@ -0,0 +1,21 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CustomModelDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Value { get; set; }
public override void Parse(Queue<byte> data)
{
Value = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
return new Queue<byte>(DataTypes.GetVarInt(Value));
}
}

View file

@ -0,0 +1,26 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class CustomNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string CustomName { get; set; } = string.Empty;
public Dictionary<string, object>? CustomNameNbt { get; set; }
public override void Parse(Queue<byte> data)
{
CustomNameNbt = DataTypes.ReadNextNbt(data);
CustomName = ChatParser.ParseText(CustomNameNbt);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(CustomNameNbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class DamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Damage { get; set; }
public override void Parse(Queue<byte> data)
{
Damage = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Damage));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class DebugStickStateComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; }
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,26 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class DyeColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Color { get; set; }
public bool ShowInTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
Color = DataTypes.ReadNextInt(data);
ShowInTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetInt(Color));
data.AddRange(DataTypes.GetBool(ShowInTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class EnchantmentGlintOverrideComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool HasGlint { get; set; }
public override void Parse(Queue<byte> data)
{
HasGlint = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(HasGlint));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,41 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class EnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfEnchantments { get; set; }
public List<Enchantment> Enchantments { get; set; } = new();
public bool ShowTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
NumberOfEnchantments = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfEnchantments; i++)
{
var registryId = DataTypes.ReadNextVarInt(data);
var level = DataTypes.ReadNextVarInt(data);
Enchantments.Add(new Enchantment(EnchantmentMapping.GetEnchantmentByRegistryId1206(DataTypes.ProtocolVersion, registryId), level));
}
ShowTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Enchantments.Count));
foreach (var enchantment in Enchantments)
{
data.AddRange(DataTypes.GetVarInt(EnchantmentMapping.GetRegistryId1206ByEnchantment(DataTypes.ProtocolVersion, enchantment.Type)));
data.AddRange(DataTypes.GetVarInt(enchantment.Level));
}
data.AddRange(DataTypes.GetBool(ShowTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,31 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class EntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; }
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}
public class BucketEntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EntityDataComponent(dataTypes, itemPalette, subComponentRegistry)
{ }
public class BlockEntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EntityDataComponent(dataTypes, itemPalette, subComponentRegistry)
{ }

View file

@ -0,0 +1,7 @@
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class FireResistantComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Mapping;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class FireworkExplosionComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public FireworkExplosionSubComponent? FireworkExplosionSubComponent { get; set; }
public override void Parse(Queue<byte> data)
{
FireworkExplosionSubComponent = (FireworkExplosionSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.FireworkExplosion, data);
}
public override Queue<byte> Serialize()
{
return FireworkExplosionSubComponent!.Serialize();
}
}

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Mapping;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class FireworksComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int FlightDuration { get; set; }
public int NumberOfExplosions { get; set; }
public List<FireworkExplosionSubComponent> Explosions { get; set; } = [];
public override void Parse(Queue<byte> data)
{
FlightDuration = DataTypes.ReadNextVarInt(data);
NumberOfExplosions = DataTypes.ReadNextVarInt(data);
if (NumberOfExplosions > 0)
{
for (var i = 0; i < NumberOfExplosions; i++)
Explosions.Add(
(FireworkExplosionSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.FireworkExplosion,
data));
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(FlightDuration));
data.AddRange(DataTypes.GetVarInt(NumberOfExplosions));
if (NumberOfExplosions > 0)
{
if (NumberOfExplosions != Explosions.Count)
throw new Exception("Can't serialize FireworksComponent because NumberOfExplosions and the lenght of Explosions differ!");
foreach (var explosion in Explosions)
data.AddRange(explosion.Serialize().ToList());
}
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class FoodComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Nutrition { get; set; }
public float Saturation { get; set; }
public bool CanAlwaysEat { get; set; }
public float SecondsToEat { get; set; }
public List<EffectSubComponent> Effects { get; set; } = new();
public override void Parse(Queue<byte> data)
{
Nutrition = DataTypes.ReadNextVarInt(data);
Saturation = DataTypes.ReadNextFloat(data);
CanAlwaysEat = DataTypes.ReadNextBool(data);
SecondsToEat = DataTypes.ReadNextFloat(data);
var numberOfEffects = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < numberOfEffects; i++)
Effects.Add((EffectSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.Effect, data));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Nutrition));
data.AddRange(DataTypes.GetFloat(Saturation));
data.AddRange(DataTypes.GetBool(CanAlwaysEat));
data.AddRange(DataTypes.GetFloat(SecondsToEat));
data.AddRange(DataTypes.GetVarInt(Effects.Count));
foreach (var effect in Effects)
data.AddRange(effect.Serialize());
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,7 @@
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class HideAdditionalTooltipComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,7 @@
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class HideTooltipComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,68 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class InstrumentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
// holder ID: 0 = inline instrument data, N>0 = registry reference (id = N-1)
public int InstrumentHolderId { get; set; }
// Inline instrument fields (only when InstrumentHolderId == 0):
// holder ID for SoundEvent: 0 = inline sound, N>0 = registry reference (id = N-1)
public int SoundEventHolderId { get; set; }
// Inline SoundEvent fields (only when SoundEventHolderId == 0):
public string? SoundLocation { get; set; }
public bool HasFixedRange { get; set; }
public float FixedRange { get; set; }
public int UseDuration { get; set; }
public float Range { get; set; }
public override void Parse(Queue<byte> data)
{
InstrumentHolderId = DataTypes.ReadNextVarInt(data);
if (InstrumentHolderId == 0)
{
SoundEventHolderId = DataTypes.ReadNextVarInt(data);
if (SoundEventHolderId == 0)
{
SoundLocation = DataTypes.ReadNextString(data);
HasFixedRange = DataTypes.ReadNextBool(data);
if (HasFixedRange)
FixedRange = DataTypes.ReadNextFloat(data);
}
UseDuration = DataTypes.ReadNextVarInt(data);
Range = DataTypes.ReadNextFloat(data);
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(InstrumentHolderId));
if (InstrumentHolderId == 0)
{
data.AddRange(DataTypes.GetVarInt(SoundEventHolderId));
if (SoundEventHolderId == 0)
{
data.AddRange(DataTypes.GetString(SoundLocation ?? ""));
data.AddRange(DataTypes.GetBool(HasFixedRange));
if (HasFixedRange)
data.AddRange(DataTypes.GetFloat(FixedRange));
}
data.AddRange(DataTypes.GetVarInt(UseDuration));
data.AddRange(DataTypes.GetFloat(Range));
}
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,10 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class IntangibleProjectileComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry)
{
}

View file

@ -0,0 +1,26 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ItemNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string ItemName { get; set; } = string.Empty;
public Dictionary<string, object>? ItemNameNbt { get; set; }
public override void Parse(Queue<byte> data)
{
ItemNameNbt = DataTypes.ReadNextNbt(data);
ItemName = ChatParser.ParseText(ItemNameNbt);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(ItemNameNbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class LockComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; }
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,43 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Mapping;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class LodestoneTrackerComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool HasGlobalPosition { get; set; }
public string Dimension { get; set; } = null!;
public Location Position { get; set; }
public bool Tracked { get; set; }
public override void Parse(Queue<byte> data)
{
HasGlobalPosition = DataTypes.ReadNextBool(data);
if (HasGlobalPosition)
{
Dimension = DataTypes.ReadNextString(data);
Position = DataTypes.ReadNextLocation(data);
}
Tracked = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(HasGlobalPosition));
if (HasGlobalPosition)
{
data.AddRange(DataTypes.GetString(Dimension));
data.AddRange(DataTypes.GetLocation(Position));
}
data.AddRange(DataTypes.GetBool(Tracked));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,39 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class LoreNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfLines { get; set; }
public List<string> Lines { get; set; } = [];
public List<Dictionary<string, object>> LinesNbt { get; set; } = [];
public override void Parse(Queue<byte> data)
{
NumberOfLines = DataTypes.ReadNextVarInt(data);
if (NumberOfLines <= 0) return;
for (var i = 0; i < NumberOfLines; i++)
{
var lineNbt = DataTypes.ReadNextNbt(data);
LinesNbt.Add(lineNbt);
Lines.Add(ChatParser.ParseText(lineNbt));
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(LinesNbt.Count));
foreach (var lineNbt in LinesNbt)
data.AddRange(DataTypes.GetNbt(lineNbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MapColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Id { get; set; }
public override void Parse(Queue<byte> data)
{
Id = DataTypes.ReadNextInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetInt(Id));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MapDecorationsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; } = new();
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MapIdComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Id { get; set; }
public override void Parse(Queue<byte> data)
{
Id = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Id));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MapPostProcessingComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Type { get; set; }
public override void Parse(Queue<byte> data)
{
Type = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Type));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MaxDamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int MaxDamage { get; set; }
public override void Parse(Queue<byte> data)
{
MaxDamage = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(MaxDamage));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class MaxStackSizeComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int MaxStackSize { get; set; }
public override void Parse(Queue<byte> data)
{
MaxStackSize = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(MaxStackSize));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class NoteBlockSoundComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string Identifier { get; set; } = null!;
public override void Parse(Queue<byte> data)
{
Identifier = DataTypes.ReadNextString(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetString(Identifier));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class OminousBottleAmplifierComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Amplifier { get; set; }
public override void Parse(Queue<byte> data)
{
Amplifier = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Amplifier));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,27 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class PotDecorationsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<int> Items { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
Items.Add(DataTypes.ReadNextVarInt(data));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Items.Count));
foreach (var item in Items)
data.AddRange(DataTypes.GetVarInt(item));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,50 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool HasPotionId { get; set; }
public int PotionId { get; set; }
public bool HasCustomColor { get; set; }
public int CustomColor { get; set; }
public List<PotionEffectSubComponent> Effects { get; set; } = new();
public override void Parse(Queue<byte> data)
{
HasPotionId = DataTypes.ReadNextBool(data);
if (HasPotionId)
PotionId = DataTypes.ReadNextVarInt(data);
HasCustomColor = DataTypes.ReadNextBool(data);
if (HasCustomColor)
CustomColor = DataTypes.ReadNextInt(data);
var numberOfEffects = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < numberOfEffects; i++)
Effects.Add((PotionEffectSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(HasPotionId));
if (HasPotionId)
data.AddRange(DataTypes.GetVarInt(PotionId));
data.AddRange(DataTypes.GetBool(HasCustomColor));
if (HasCustomColor)
data.AddRange(DataTypes.GetInt(CustomColor));
data.AddRange(DataTypes.GetVarInt(Effects.Count));
foreach (var effect in Effects)
data.AddRange(effect.Serialize());
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ProfileComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool HasName { get; set; }
public string? Name { get; set; } = null!;
public bool HasUniqueId { get; set; }
public Guid Uuid { get; set; }
public int NumberOfProperties { get; set; }
public List<ProfileProperty> ProfileProperties { get; set; } = [];
public bool IsFullProfile { get; set; }
public string? BodyAssetId { get; set; }
public string? CapeAssetId { get; set; }
public string? ElytraAssetId { get; set; }
public ProfileSkinModel? Model { get; set; }
public override void Parse(Queue<byte> data)
{
ResetState();
if (DataTypes.ProtocolVersion >= Protocol18Handler.MC_1_21_9_Version)
{
ParseResolvableProfile(data);
return;
}
ParseLegacyProfile(data);
}
public override Queue<byte> Serialize()
{
return DataTypes.ProtocolVersion >= Protocol18Handler.MC_1_21_9_Version
? SerializeResolvableProfile()
: SerializeLegacyProfile();
}
private void ResetState()
{
HasName = false;
Name = null;
HasUniqueId = false;
Uuid = Guid.Empty;
NumberOfProperties = 0;
ProfileProperties = [];
IsFullProfile = false;
BodyAssetId = null;
CapeAssetId = null;
ElytraAssetId = null;
Model = null;
}
private void ParseLegacyProfile(Queue<byte> data)
{
HasName = DataTypes.ReadNextBool(data);
if (HasName)
Name = DataTypes.ReadNextString(data);
HasUniqueId = DataTypes.ReadNextBool(data);
if (HasUniqueId)
Uuid = DataTypes.ReadNextUUID(data);
NumberOfProperties = DataTypes.ReadNextVarInt(data);
ProfileProperties = ReadProfileProperties(data, NumberOfProperties);
}
private void ParseResolvableProfile(Queue<byte> data)
{
IsFullProfile = DataTypes.ReadNextBool(data);
if (IsFullProfile)
{
HasUniqueId = true;
Uuid = DataTypes.ReadNextUUID(data);
HasName = true;
Name = DataTypes.ReadNextString(data);
NumberOfProperties = DataTypes.ReadNextVarInt(data);
ProfileProperties = ReadProfileProperties(data, NumberOfProperties);
}
else
{
HasName = DataTypes.ReadNextBool(data);
if (HasName)
Name = DataTypes.ReadNextString(data);
HasUniqueId = DataTypes.ReadNextBool(data);
if (HasUniqueId)
Uuid = DataTypes.ReadNextUUID(data);
NumberOfProperties = DataTypes.ReadNextVarInt(data);
ProfileProperties = ReadProfileProperties(data, NumberOfProperties);
}
BodyAssetId = ReadOptionalResourceLocation(data);
CapeAssetId = ReadOptionalResourceLocation(data);
ElytraAssetId = ReadOptionalResourceLocation(data);
if (DataTypes.ReadNextBool(data))
Model = DataTypes.ReadNextBool(data) ? ProfileSkinModel.Slim : ProfileSkinModel.Wide;
}
private Queue<byte> SerializeLegacyProfile()
{
var data = new List<byte>();
NumberOfProperties = ProfileProperties.Count;
data.AddRange(DataTypes.GetBool(HasName));
if (HasName)
data.AddRange(DataTypes.GetString(Name ?? ""));
data.AddRange(DataTypes.GetBool(HasUniqueId));
if (HasUniqueId)
data.AddRange(DataTypes.GetUUID(Uuid));
data.AddRange(DataTypes.GetVarInt(NumberOfProperties));
SerializeProfileProperties(data);
return new Queue<byte>(data);
}
private Queue<byte> SerializeResolvableProfile()
{
var data = new List<byte>();
NumberOfProperties = ProfileProperties.Count;
data.AddRange(DataTypes.GetBool(IsFullProfile));
if (IsFullProfile)
{
if (!HasUniqueId)
throw new NullReferenceException("Can't serialize the ProfileComponent because a full profile requires a UUID!");
data.AddRange(DataTypes.GetUUID(Uuid));
data.AddRange(DataTypes.GetString(Name ?? ""));
}
else
{
data.AddRange(DataTypes.GetBool(HasName));
if (HasName)
data.AddRange(DataTypes.GetString(Name ?? ""));
data.AddRange(DataTypes.GetBool(HasUniqueId));
if (HasUniqueId)
data.AddRange(DataTypes.GetUUID(Uuid));
}
data.AddRange(DataTypes.GetVarInt(NumberOfProperties));
SerializeProfileProperties(data);
SerializeOptionalResourceLocation(data, BodyAssetId);
SerializeOptionalResourceLocation(data, CapeAssetId);
SerializeOptionalResourceLocation(data, ElytraAssetId);
data.AddRange(DataTypes.GetBool(Model.HasValue));
if (Model.HasValue)
data.AddRange(DataTypes.GetBool(Model.Value == ProfileSkinModel.Slim));
return new Queue<byte>(data);
}
private List<ProfileProperty> ReadProfileProperties(Queue<byte> data, int count)
{
var properties = new List<ProfileProperty>(count);
for (var i = 0; i < count; i++)
{
var propertyName = DataTypes.ReadNextString(data);
var propertyValue = DataTypes.ReadNextString(data);
var hasSignature = DataTypes.ReadNextBool(data);
var signature = hasSignature ? DataTypes.ReadNextString(data) : null;
properties.Add(new ProfileProperty(propertyName, propertyValue, hasSignature, signature));
}
return properties;
}
private void SerializeProfileProperties(List<byte> data)
{
foreach (var profileProperty in ProfileProperties)
{
data.AddRange(DataTypes.GetString(profileProperty.Name));
data.AddRange(DataTypes.GetString(profileProperty.Value));
data.AddRange(DataTypes.GetBool(profileProperty.HasSignature));
if (!profileProperty.HasSignature)
continue;
if (string.IsNullOrEmpty(profileProperty.Signature))
throw new NullReferenceException("Can't serialize the ProfileComponent because HasSignature is true, but the Signature is null/empty!");
data.AddRange(DataTypes.GetString(profileProperty.Signature));
}
}
private string? ReadOptionalResourceLocation(Queue<byte> data)
{
return DataTypes.ReadNextBool(data) ? DataTypes.ReadNextString(data) : null;
}
private void SerializeOptionalResourceLocation(List<byte> data, string? resourceLocation)
{
data.AddRange(DataTypes.GetBool(!string.IsNullOrEmpty(resourceLocation)));
if (!string.IsNullOrEmpty(resourceLocation))
data.AddRange(DataTypes.GetString(resourceLocation));
}
}
public record ProfileProperty(string Name, string Value, bool HasSignature, string? Signature);
public enum ProfileSkinModel
{
Wide,
Slim
}

View file

@ -0,0 +1,24 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class RarityComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public ItemRarity Rarity { get; set; }
public override void Parse(Queue<byte> data)
{
Rarity = (ItemRarity)DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt((int)Rarity));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class RecipesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public Dictionary<string, object>? Nbt { get; set; }
public override void Parse(Queue<byte> data)
{
Nbt = DataTypes.ReadNextNbt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetNbt(Nbt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class RepairCostComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Cost { get; set; }
public override void Parse(Queue<byte> data)
{
Cost = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Cost));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,9 @@
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class StoredEnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EnchantmentsComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class SuspiciousStewEffectsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfEffects { get; set; }
public List<SuspiciousStewEffect> Effects { get; set; } = new();
public override void Parse(Queue<byte> data)
{
NumberOfEffects = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfEffects; i++)
Effects.Add(new SuspiciousStewEffect(DataTypes.ReadNextVarInt(data), DataTypes.ReadNextVarInt(data)));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfEffects));
if (NumberOfEffects != Effects.Count)
throw new InvalidOperationException("Can not serialize SuspiciousStewEffectsComponent1206 because umberOfEffects != Effects.Count!");
foreach (var effect in Effects)
{
data.AddRange(DataTypes.GetVarInt(effect.TypeId));
data.AddRange(DataTypes.GetVarInt(effect.Duration));
}
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class ToolComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int NumberOfRules { get; set; }
public List<RuleSubComponent> Rules { get; set; } = new();
public float DefaultMiningSpeed { get; set; }
public int DamagePerBlock { get; set; }
public override void Parse(Queue<byte> data)
{
NumberOfRules = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfRules; i++)
Rules.Add((RuleSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.Rule, data));
DefaultMiningSpeed = DataTypes.ReadNextFloat(data);
DamagePerBlock = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(NumberOfRules));
if (Rules.Count != NumberOfRules)
throw new ArgumentNullException($"Can not serialize a ToolComponent1206 when the Rules count != NumberOfRules!");
foreach (var rule in Rules)
data.AddRange(rule.Serialize());
data.AddRange(DataTypes.GetFloat(DefaultMiningSpeed));
data.AddRange(DataTypes.GetVarInt(DamagePerBlock));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int TrimMaterialType { get; set; }
public string AssetName { get; set; } = null!;
public int Ingredient { get; set; }
public float ItemModelIndex { get; set; }
public int NumberOfOverrides { get; set; }
public List<TrimAssetOverride>? Overrides { get; set; }
public Dictionary<string, object>? DescriptionNbt { get; set; }
public string Description { get; set; } = null!;
public int TrimPatternType { get; set; }
public string TrimPatternTypeAssetName { get; set; } = null!;
public int TemplateItem { get; set; }
public Dictionary<string, object>? TrimPatternTypeDescriptionNbt { get; set; }
public string TrimPatternTypeDescription { get; set; } = null!;
public bool Decal { get; set; }
public bool ShowInTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
TrimMaterialType = DataTypes.ReadNextVarInt(data);
if (TrimMaterialType == 0)
{
AssetName = DataTypes.ReadNextString(data);
Ingredient = DataTypes.ReadNextVarInt(data);
ItemModelIndex = DataTypes.ReadNextFloat(data);
NumberOfOverrides = DataTypes.ReadNextVarInt(data);
if (NumberOfOverrides > 0)
{
Overrides = [];
for (var i = 0; i < NumberOfOverrides; i++)
Overrides.Add(new TrimAssetOverride(DataTypes.ReadNextVarInt(data),
DataTypes.ReadNextString(data)));
}
DescriptionNbt = DataTypes.ReadNextNbt(data);
Description = ChatParser.ParseText(DescriptionNbt);
}
TrimPatternType = DataTypes.ReadNextVarInt(data);
if (TrimPatternType == 0)
{
TrimPatternTypeAssetName = DataTypes.ReadNextString(data);
TemplateItem = DataTypes.ReadNextVarInt(data);
TrimPatternTypeDescriptionNbt = DataTypes.ReadNextNbt(data);
TrimPatternTypeDescription = ChatParser.ParseText(TrimPatternTypeDescriptionNbt);
Decal = DataTypes.ReadNextBool(data);
}
ShowInTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(TrimMaterialType));
if (TrimMaterialType == 0)
{
if (string.IsNullOrEmpty(AssetName))
throw new NullReferenceException("Can't serialize the TrimComponent because the Asset Name is null!");
data.AddRange(DataTypes.GetString(AssetName));
data.AddRange(DataTypes.GetVarInt(Ingredient));
data.AddRange(DataTypes.GetFloat(ItemModelIndex));
data.AddRange(DataTypes.GetVarInt(NumberOfOverrides));
if (NumberOfOverrides > 0)
{
if (NumberOfOverrides != Overrides?.Count)
throw new NullReferenceException("Can't serialize the TrimComponent because value of NumberOfOverrides and the size of Overrides don't match!");
foreach (var (armorMaterialType, assetName) in Overrides)
{
data.AddRange(DataTypes.GetVarInt(armorMaterialType));
data.AddRange(DataTypes.GetString(assetName));
}
}
data.AddRange(DataTypes.GetNbt(DescriptionNbt));
}
data.AddRange(DataTypes.GetVarInt(TrimPatternType));
if (TrimPatternType == 0)
{
if (string.IsNullOrEmpty(TrimPatternTypeAssetName))
throw new NullReferenceException("Can't serialize the TrimComponent because the TrimPatternTypeAssetName is null!");
data.AddRange(DataTypes.GetString(TrimPatternTypeAssetName));
data.AddRange(DataTypes.GetVarInt(TemplateItem));
data.AddRange(DataTypes.GetNbt(TrimPatternTypeDescriptionNbt));
data.AddRange(DataTypes.GetBool(Decal));
}
data.AddRange(DataTypes.GetBool(ShowInTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class UnbreakableComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool Unbreakable { get; set; }
public override void Parse(Queue<byte> data)
{
Unbreakable = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(Unbreakable));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class WritableBookContentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<BookPage> Pages { get; set; } = [];
public override void Parse(Queue<byte> data)
{
var count = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < count; i++)
{
var rawContent = DataTypes.ReadNextString(data);
var hasFilteredContent = DataTypes.ReadNextBool(data);
var filteredContent = null as string;
if (hasFilteredContent)
filteredContent = DataTypes.ReadNextString(data);
Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent));
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Pages.Count));
foreach (var page in Pages)
{
data.AddRange(DataTypes.GetString(page.RawContent));
data.AddRange(DataTypes.GetBool(page.HasFilteredContent));
if (page.HasFilteredContent)
{
if (page.FilteredContent is null)
throw new InvalidOperationException("Can not serialize WritableBookContentComponent because page.HasFilteredContent = true, but FilteredContent is null!");
data.AddRange(DataTypes.GetString(page.FilteredContent));
}
}
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
public class WrittenBookContentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string RawTitle { get; set; } = null!;
public bool HasFilteredTitle { get; set; }
public string? FilteredTitle { get; set; }
public string Author { get; set; } = null!;
public int Generation { get; set; }
public int NumberOfPages { get; set; }
public List<BookPage> Pages { get; set; } = [];
public bool Resolved { get; set; }
public override void Parse(Queue<byte> data)
{
RawTitle = DataTypes.ReadNextString(data);
HasFilteredTitle = DataTypes.ReadNextBool(data);
if (HasFilteredTitle)
FilteredTitle = DataTypes.ReadNextString(data);
Author = DataTypes.ReadNextString(data);
Generation = DataTypes.ReadNextVarInt(data);
NumberOfPages = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < NumberOfPages; i++)
{
var (rawContent, rawContentNbt) = ReadPageComponent(data);
var hasFilteredContent = DataTypes.ReadNextBool(data);
Dictionary<string, object>? filteredContentNbt = null;
string? filteredContent = null;
if (hasFilteredContent)
(filteredContent, filteredContentNbt) = ReadPageComponent(data);
Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent, rawContentNbt, filteredContentNbt));
}
Resolved = DataTypes.ReadNextBool(data);
}
private (string Content, Dictionary<string, object> Nbt) ReadPageComponent(Queue<byte> data)
{
// Hypixel sent page payloads in the string-shaped form on this structured-book path,
// so keep the parser tolerant while still preserving the raw data for serialization.
Queue<byte> fallbackData = new(data);
try
{
var nbt = DataTypes.ReadNextNbt(data);
return (ChatParser.ParseText(nbt), nbt);
}
catch (System.IO.InvalidDataException)
{
data.Clear();
foreach (var b in fallbackData)
data.Enqueue(b);
var json = DataTypes.ReadNextString(data);
return (ChatParser.ParseText(json), new Dictionary<string, object> { [""] = json });
}
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetString(RawTitle));
data.AddRange(DataTypes.GetBool(HasFilteredTitle));
if (HasFilteredTitle)
{
if (FilteredTitle is null)
throw new InvalidOperationException("Can not serialize WrittenBookContentComponent because HasFilteredTitle is true but FilteredTitle is null!");
data.AddRange(DataTypes.GetString(FilteredTitle));
}
data.AddRange(DataTypes.GetString(Author));
data.AddRange(DataTypes.GetVarInt(Generation));
data.AddRange(DataTypes.GetVarInt(Pages.Count));
foreach (var page in Pages)
{
data.AddRange(DataTypes.GetNbt(page.RawContentNbt));
data.AddRange(DataTypes.GetBool(page.HasFilteredContent));
if (page.HasFilteredContent)
data.AddRange(DataTypes.GetNbt(page.FilteredContentNbt));
}
data.AddRange(DataTypes.GetBool(Resolved));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
public class JukeBoxPlayableComponent121(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool IsHolder { get; set; }
public int HolderId { get; set; }
public string? ResourceKey { get; set; }
public SoundEventSubComponent? SoundEvent { get; set; }
public Dictionary<string, object>? DescriptionNbt { get; set; }
public string Description { get; set; } = string.Empty;
public float Duration { get; set; }
public int ComparatorOutput { get; set; }
public bool ShowTooltip { get; set; }
public override void Parse(Queue<byte> data)
{
IsHolder = DataTypes.ReadNextBool(data);
if (IsHolder)
{
HolderId = DataTypes.ReadNextVarInt(data);
if (HolderId == 0)
{
SoundEvent = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
DescriptionNbt = DataTypes.ReadNextNbt(data);
Description = ChatParser.ParseText(DescriptionNbt);
Duration = DataTypes.ReadNextFloat(data);
ComparatorOutput = DataTypes.ReadNextVarInt(data);
}
}
else
{
ResourceKey = DataTypes.ReadNextString(data);
}
ShowTooltip = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(IsHolder));
if (IsHolder)
{
data.AddRange(DataTypes.GetVarInt(HolderId));
if (HolderId == 0)
{
if (SoundEvent is null)
throw new ArgumentNullException(nameof(SoundEvent), "Inline jukebox song requires a sound event.");
if (DescriptionNbt is null)
throw new ArgumentNullException(nameof(DescriptionNbt), "Inline jukebox song requires a description.");
data.AddRange(SoundEvent.Serialize());
data.AddRange(DataTypes.GetNbt(DescriptionNbt));
data.AddRange(DataTypes.GetFloat(Duration));
data.AddRange(DataTypes.GetVarInt(ComparatorOutput));
}
}
else
{
if (string.IsNullOrEmpty(ResourceKey))
throw new ArgumentNullException(nameof(ResourceKey), "Resource key is required for key-backed jukebox songs.");
data.AddRange(DataTypes.GetString(ResourceKey));
}
data.AddRange(DataTypes.GetBool(ShowTooltip));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,38 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
public class AttackRangeComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public float MinRange { get; set; }
public float MaxRange { get; set; }
public float MinCreativeRange { get; set; }
public float MaxCreativeRange { get; set; }
public float HitboxMargin { get; set; }
public float MobFactor { get; set; }
public override void Parse(Queue<byte> data)
{
MinRange = DataTypes.ReadNextFloat(data);
MaxRange = DataTypes.ReadNextFloat(data);
MinCreativeRange = DataTypes.ReadNextFloat(data);
MaxCreativeRange = DataTypes.ReadNextFloat(data);
HitboxMargin = DataTypes.ReadNextFloat(data);
MobFactor = DataTypes.ReadNextFloat(data);
}
public override Queue<byte> Serialize()
{
var bytes = new List<byte>();
bytes.AddRange(DataTypes.GetFloat(MinRange));
bytes.AddRange(DataTypes.GetFloat(MaxRange));
bytes.AddRange(DataTypes.GetFloat(MinCreativeRange));
bytes.AddRange(DataTypes.GetFloat(MaxCreativeRange));
bytes.AddRange(DataTypes.GetFloat(HitboxMargin));
bytes.AddRange(DataTypes.GetFloat(MobFactor));
return new Queue<byte>(bytes);
}
}

View file

@ -0,0 +1,72 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
public class KineticWeaponComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int ContactCooldownTicks { get; set; }
public int DelayTicks { get; set; }
public KineticWeaponConditionData? DismountConditions { get; set; }
public KineticWeaponConditionData? KnockbackConditions { get; set; }
public KineticWeaponConditionData? DamageConditions { get; set; }
public float ForwardMovement { get; set; }
public float DamageMultiplier { get; set; }
public SoundEventHolderData? Sound { get; set; }
public SoundEventHolderData? HitSound { get; set; }
public override void Parse(Queue<byte> data)
{
ContactCooldownTicks = DataTypes.ReadNextVarInt(data);
DelayTicks = DataTypes.ReadNextVarInt(data);
DismountConditions = ReadOptionalCondition(data);
KnockbackConditions = ReadOptionalCondition(data);
DamageConditions = ReadOptionalCondition(data);
ForwardMovement = DataTypes.ReadNextFloat(data);
DamageMultiplier = DataTypes.ReadNextFloat(data);
Sound = StructuredComponentCodecHelpers.ReadOptionalSoundEventHolder(DataTypes, data);
HitSound = StructuredComponentCodecHelpers.ReadOptionalSoundEventHolder(DataTypes, data);
}
private KineticWeaponConditionData? ReadOptionalCondition(Queue<byte> data)
{
if (!DataTypes.ReadNextBool(data))
return null;
return new KineticWeaponConditionData(
DataTypes.ReadNextVarInt(data),
DataTypes.ReadNextFloat(data),
DataTypes.ReadNextFloat(data));
}
private void WriteOptionalCondition(List<byte> data, KineticWeaponConditionData? condition)
{
data.AddRange(DataTypes.GetBool(condition is not null));
if (condition is null)
return;
data.AddRange(DataTypes.GetVarInt(condition.MaxDurationTicks));
data.AddRange(DataTypes.GetFloat(condition.MinSpeed));
data.AddRange(DataTypes.GetFloat(condition.MinRelativeSpeed));
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(ContactCooldownTicks));
data.AddRange(DataTypes.GetVarInt(DelayTicks));
WriteOptionalCondition(data, DismountConditions);
WriteOptionalCondition(data, KnockbackConditions);
WriteOptionalCondition(data, DamageConditions);
data.AddRange(DataTypes.GetFloat(ForwardMovement));
data.AddRange(DataTypes.GetFloat(DamageMultiplier));
StructuredComponentCodecHelpers.WriteOptionalSoundEventHolder(DataTypes, data, Sound);
StructuredComponentCodecHelpers.WriteOptionalSoundEventHolder(DataTypes, data, HitSound);
return new Queue<byte>(data);
}
}
public sealed record KineticWeaponConditionData(int MaxDurationTicks, float MinSpeed, float MinRelativeSpeed);

View file

@ -0,0 +1,33 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
public class PiercingWeaponComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool DealsKnockback { get; set; }
public bool Dismounts { get; set; }
public SoundEventHolderData? Sound { get; set; }
public SoundEventHolderData? HitSound { get; set; }
public override void Parse(Queue<byte> data)
{
DealsKnockback = DataTypes.ReadNextBool(data);
Dismounts = DataTypes.ReadNextBool(data);
Sound = StructuredComponentCodecHelpers.ReadOptionalSoundEventHolder(DataTypes, data);
HitSound = StructuredComponentCodecHelpers.ReadOptionalSoundEventHolder(DataTypes, data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(DealsKnockback));
data.AddRange(DataTypes.GetBool(Dismounts));
StructuredComponentCodecHelpers.WriteOptionalSoundEventHolder(DataTypes, data, Sound);
StructuredComponentCodecHelpers.WriteOptionalSoundEventHolder(DataTypes, data, HitSound);
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,38 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
/// <summary>
/// EitherHolder backed by holderRegistry (VarInt = raw registry ID, 0 is valid).
/// Used for DamageType and ZombieNautilusVariant where the holder codec is holderRegistry(),
/// unlike the holder() codec used in SoundEvent (where 0 means inline).
/// </summary>
public class RegistryEitherHolderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool IsHolder { get; set; }
public int HolderId { get; set; }
public string? ResourceKey { get; set; }
public override void Parse(Queue<byte> data)
{
IsHolder = DataTypes.ReadNextBool(data);
if (IsHolder)
HolderId = DataTypes.ReadNextVarInt(data);
else
ResourceKey = DataTypes.ReadNextString(data);
}
public override Queue<byte> Serialize()
{
var bytes = new List<byte>();
bytes.AddRange(DataTypes.GetBool(IsHolder));
if (IsHolder)
bytes.AddRange(DataTypes.GetVarInt(HolderId));
else
bytes.AddRange(DataTypes.GetString(ResourceKey ?? ""));
return new Queue<byte>(bytes);
}
}

View file

@ -0,0 +1,26 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
public class SwingAnimationComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int AnimationType { get; set; }
public int Duration { get; set; }
public override void Parse(Queue<byte> data)
{
AnimationType = DataTypes.ReadNextVarInt(data);
Duration = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var bytes = new List<byte>();
bytes.AddRange(DataTypes.GetVarInt(AnimationType));
bytes.AddRange(DataTypes.GetVarInt(Duration));
return new Queue<byte>(bytes);
}
}

View file

@ -0,0 +1,29 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
public class UseEffectsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool CanSprint { get; set; }
public bool InteractVibrations { get; set; }
public float SpeedMultiplier { get; set; }
public override void Parse(Queue<byte> data)
{
CanSprint = DataTypes.ReadNextBool(data);
InteractVibrations = DataTypes.ReadNextBool(data);
SpeedMultiplier = DataTypes.ReadNextFloat(data);
}
public override Queue<byte> Serialize()
{
var bytes = new List<byte>();
bytes.AddRange(DataTypes.GetBool(CanSprint));
bytes.AddRange(DataTypes.GetBool(InteractVibrations));
bytes.AddRange(DataTypes.GetFloat(SpeedMultiplier));
return new Queue<byte>(bytes);
}
}

View file

@ -0,0 +1,129 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class ConsumableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public float ConsumeSeconds { get; set; }
public int Animation { get; set; }
public SoundEventSubComponent? Sound { get; set; }
public bool HasConsumeParticles { get; set; }
public List<ConsumeEffectData> Effects { get; set; } = new();
public override void Parse(Queue<byte> data)
{
ConsumeSeconds = DataTypes.ReadNextFloat(data);
Animation = DataTypes.ReadNextVarInt(data);
Sound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
HasConsumeParticles = DataTypes.ReadNextBool(data);
var effectCount = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < effectCount; i++)
{
var effectTypeId = DataTypes.ReadNextVarInt(data);
var effectData = ReadConsumeEffectPayload(effectTypeId, data);
Effects.Add(new ConsumeEffectData(effectTypeId, effectData));
}
}
private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue<byte> data)
{
var payload = new List<byte>();
switch (effectTypeId)
{
case 0: // apply_effects: List<MobEffectInstance> + probability(float)
var effectCount = DataTypes.ReadNextVarInt(data);
payload.AddRange(DataTypes.GetVarInt(effectCount));
for (var i = 0; i < effectCount; i++)
payload.AddRange(ReadMobEffectInstance(data));
payload.AddRange(DataTypes.GetFloat(DataTypes.ReadNextFloat(data)));
break;
case 1: // remove_effects: HolderSet<MobEffect>
payload.AddRange(ReadHolderSet(data));
break;
case 2: // clear_all_effects: empty
break;
case 3: // teleport_randomly: float diameter
payload.AddRange(DataTypes.GetFloat(DataTypes.ReadNextFloat(data)));
break;
case 4: // play_sound: Holder<SoundEvent>
var sound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
payload.AddRange(sound.Serialize());
break;
}
return payload.ToArray();
}
private byte[] ReadMobEffectInstance(Queue<byte> data)
{
var result = new List<byte>();
var effectId = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(effectId));
result.AddRange(ReadMobEffectDetails(data));
return result.ToArray();
}
private byte[] ReadMobEffectDetails(Queue<byte> data)
{
var result = new List<byte>();
var amplifier = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(amplifier));
var duration = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(duration));
var ambient = DataTypes.ReadNextBool(data);
result.AddRange(DataTypes.GetBool(ambient));
var showParticles = DataTypes.ReadNextBool(data);
result.AddRange(DataTypes.GetBool(showParticles));
var showIcon = DataTypes.ReadNextBool(data);
result.AddRange(DataTypes.GetBool(showIcon));
var hasHiddenEffect = DataTypes.ReadNextBool(data);
result.AddRange(DataTypes.GetBool(hasHiddenEffect));
if (hasHiddenEffect)
result.AddRange(ReadMobEffectDetails(data));
return result.ToArray();
}
private byte[] ReadHolderSet(Queue<byte> data)
{
var result = new List<byte>();
var type = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(type));
if (type == 0)
{
var tagName = DataTypes.ReadNextString(data);
result.AddRange(DataTypes.GetString(tagName));
}
else
{
for (var i = 0; i < type - 1; i++)
{
var id = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(id));
}
}
return result.ToArray();
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetFloat(ConsumeSeconds));
data.AddRange(DataTypes.GetVarInt(Animation));
if (Sound is not null) data.AddRange(Sound.Serialize());
data.AddRange(DataTypes.GetBool(HasConsumeParticles));
data.AddRange(DataTypes.GetVarInt(Effects.Count));
foreach (var effect in Effects)
{
data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId));
data.AddRange(effect.Payload);
}
return new Queue<byte>(data);
}
public record ConsumeEffectData(int EffectTypeId, byte[] Payload);
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class DamageResistantComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string Types { get; set; } = null!;
public override void Parse(Queue<byte> data)
{
Types = DataTypes.ReadNextString(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetString(Types));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,106 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class DeathProtectionComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public List<ConsumeEffectData> DeathEffects { get; set; } = new();
public override void Parse(Queue<byte> data)
{
var effectCount = DataTypes.ReadNextVarInt(data);
for (var i = 0; i < effectCount; i++)
{
var effectTypeId = DataTypes.ReadNextVarInt(data);
var effectData = ReadConsumeEffectPayload(effectTypeId, data);
DeathEffects.Add(new ConsumeEffectData(effectTypeId, effectData));
}
}
private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue<byte> data)
{
var payload = new List<byte>();
switch (effectTypeId)
{
case 0: // apply_effects
var effectCount = DataTypes.ReadNextVarInt(data);
payload.AddRange(DataTypes.GetVarInt(effectCount));
for (var i = 0; i < effectCount; i++)
payload.AddRange(ReadMobEffectInstance(data));
payload.AddRange(DataTypes.GetFloat(DataTypes.ReadNextFloat(data)));
break;
case 1: // remove_effects
payload.AddRange(ReadHolderSet(data));
break;
case 2: // clear_all_effects
break;
case 3: // teleport_randomly
payload.AddRange(DataTypes.GetFloat(DataTypes.ReadNextFloat(data)));
break;
case 4: // play_sound
var sound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
payload.AddRange(sound.Serialize());
break;
}
return payload.ToArray();
}
private byte[] ReadMobEffectInstance(Queue<byte> data)
{
var result = new List<byte>();
result.AddRange(DataTypes.GetVarInt(DataTypes.ReadNextVarInt(data)));
result.AddRange(ReadMobEffectDetails(data));
return result.ToArray();
}
private byte[] ReadMobEffectDetails(Queue<byte> data)
{
var result = new List<byte>();
result.AddRange(DataTypes.GetVarInt(DataTypes.ReadNextVarInt(data)));
result.AddRange(DataTypes.GetVarInt(DataTypes.ReadNextVarInt(data)));
result.AddRange(DataTypes.GetBool(DataTypes.ReadNextBool(data)));
result.AddRange(DataTypes.GetBool(DataTypes.ReadNextBool(data)));
result.AddRange(DataTypes.GetBool(DataTypes.ReadNextBool(data)));
var hasHidden = DataTypes.ReadNextBool(data);
result.AddRange(DataTypes.GetBool(hasHidden));
if (hasHidden)
result.AddRange(ReadMobEffectDetails(data));
return result.ToArray();
}
private byte[] ReadHolderSet(Queue<byte> data)
{
var result = new List<byte>();
var type = DataTypes.ReadNextVarInt(data);
result.AddRange(DataTypes.GetVarInt(type));
if (type == 0)
{
result.AddRange(DataTypes.GetString(DataTypes.ReadNextString(data)));
}
else
{
for (var i = 0; i < type - 1; i++)
result.AddRange(DataTypes.GetVarInt(DataTypes.ReadNextVarInt(data)));
}
return result.ToArray();
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(DeathEffects.Count));
foreach (var effect in DeathEffects)
{
data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId));
data.AddRange(effect.Payload);
}
return new Queue<byte>(data);
}
public record ConsumeEffectData(int EffectTypeId, byte[] Payload);
}

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class EnchantableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Value { get; set; }
public override void Parse(Queue<byte> data)
{
Value = DataTypes.ReadNextVarInt(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Value));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,94 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class EquippableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Slot { get; set; }
public SoundEventSubComponent? EquipSound { get; set; }
public bool HasModel { get; set; }
public string? Model { get; set; }
public bool HasCameraOverlay { get; set; }
public string? CameraOverlay { get; set; }
public bool HasAllowedEntities { get; set; }
public int AllowedEntitiesType { get; set; }
public string? AllowedEntitiesTag { get; set; }
public List<int>? AllowedEntitiesIds { get; set; }
public bool Dispensable { get; set; }
public bool Swappable { get; set; }
public bool DamageOnHurt { get; set; }
public override void Parse(Queue<byte> data)
{
Slot = DataTypes.ReadNextVarInt(data);
EquipSound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
HasModel = DataTypes.ReadNextBool(data);
if (HasModel)
Model = DataTypes.ReadNextString(data);
HasCameraOverlay = DataTypes.ReadNextBool(data);
if (HasCameraOverlay)
CameraOverlay = DataTypes.ReadNextString(data);
HasAllowedEntities = DataTypes.ReadNextBool(data);
if (HasAllowedEntities)
{
AllowedEntitiesType = DataTypes.ReadNextVarInt(data);
if (AllowedEntitiesType == 0)
{
AllowedEntitiesTag = DataTypes.ReadNextString(data);
}
else
{
AllowedEntitiesIds = new List<int>();
for (var i = 0; i < AllowedEntitiesType - 1; i++)
AllowedEntitiesIds.Add(DataTypes.ReadNextVarInt(data));
}
}
Dispensable = DataTypes.ReadNextBool(data);
Swappable = DataTypes.ReadNextBool(data);
DamageOnHurt = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Slot));
if (EquipSound is not null) data.AddRange(EquipSound.Serialize());
data.AddRange(DataTypes.GetBool(HasModel));
if (HasModel && Model is not null)
data.AddRange(DataTypes.GetString(Model));
data.AddRange(DataTypes.GetBool(HasCameraOverlay));
if (HasCameraOverlay && CameraOverlay is not null)
data.AddRange(DataTypes.GetString(CameraOverlay));
data.AddRange(DataTypes.GetBool(HasAllowedEntities));
if (HasAllowedEntities)
{
data.AddRange(DataTypes.GetVarInt(AllowedEntitiesType));
if (AllowedEntitiesType == 0 && AllowedEntitiesTag is not null)
{
data.AddRange(DataTypes.GetString(AllowedEntitiesTag));
}
else if (AllowedEntitiesIds is not null)
{
foreach (var id in AllowedEntitiesIds)
data.AddRange(DataTypes.GetVarInt(id));
}
}
data.AddRange(DataTypes.GetBool(Dispensable));
data.AddRange(DataTypes.GetBool(Swappable));
data.AddRange(DataTypes.GetBool(DamageOnHurt));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,29 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class FoodComponent1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public int Nutrition { get; set; }
public float Saturation { get; set; }
public bool CanAlwaysEat { get; set; }
public override void Parse(Queue<byte> data)
{
Nutrition = DataTypes.ReadNextVarInt(data);
Saturation = DataTypes.ReadNextFloat(data);
CanAlwaysEat = DataTypes.ReadNextBool(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetVarInt(Nutrition));
data.AddRange(DataTypes.GetFloat(Saturation));
data.AddRange(DataTypes.GetBool(CanAlwaysEat));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,8 @@
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class GliderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);

View file

@ -0,0 +1,23 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class ItemModelComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public string Identifier { get; set; } = null!;
public override void Parse(Queue<byte> data)
{
Identifier = DataTypes.ReadNextString(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetString(Identifier));
return new Queue<byte>(data);
}
}

View file

@ -0,0 +1,61 @@
using System.Collections.Generic;
using MinecraftClient.Inventory.ItemPalettes;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
public class PotionContentsComponent1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
{
public bool HasPotionId { get; set; }
public int PotionId { get; set; }
public bool HasCustomColor { get; set; }
public int CustomColor { get; set; }
public List<PotionEffectSubComponent> Effects { get; set; } = [];
public bool HasCustomName { get; set; }
public string? CustomName { get; set; }
public override void Parse(Queue<byte> data)
{
HasPotionId = DataTypes.ReadNextBool(data);
if (HasPotionId)
PotionId = DataTypes.ReadNextVarInt(data);
HasCustomColor = DataTypes.ReadNextBool(data);
if (HasCustomColor)
CustomColor = DataTypes.ReadNextInt(data);
var numberOfEffects = DataTypes.ReadNextVarInt(data);
Effects = new List<PotionEffectSubComponent>(numberOfEffects);
for (var i = 0; i < numberOfEffects; i++)
Effects.Add((PotionEffectSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data));
HasCustomName = DataTypes.ReadNextBool(data);
if (HasCustomName)
CustomName = DataTypes.ReadNextString(data);
}
public override Queue<byte> Serialize()
{
var data = new List<byte>();
data.AddRange(DataTypes.GetBool(HasPotionId));
if (HasPotionId)
data.AddRange(DataTypes.GetVarInt(PotionId));
data.AddRange(DataTypes.GetBool(HasCustomColor));
if (HasCustomColor)
data.AddRange(DataTypes.GetInt(CustomColor));
data.AddRange(DataTypes.GetVarInt(Effects.Count));
foreach (var effect in Effects)
data.AddRange(effect.Serialize());
data.AddRange(DataTypes.GetBool(HasCustomName));
if (HasCustomName && CustomName is not null)
data.AddRange(DataTypes.GetString(CustomName));
return new Queue<byte>(data);
}
}

Some files were not shown because too many files have changed in this diff Show more