From c94be261fd86edccb530a4a1287ac8a00f567b38 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 2 May 2026 17:52:17 +0200 Subject: [PATCH 1/4] Added Book Support --- MinecraftClient/Commands/Book.cs | 293 ++++++++++++++++++ MinecraftClient/Inventory/BookContent.cs | 183 +++++++++++ MinecraftClient/Inventory/Item.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette113.cs | 22 ++ .../Inventory/ItemPalettes/ItemPalette1132.cs | 22 ++ .../Inventory/ItemPalettes/ItemPalette114.cs | 22 ++ MinecraftClient/McClient.cs | 77 +++++ .../Protocol/Handlers/DataTypes.cs | 4 +- .../Protocol/Handlers/Protocol16.cs | 5 + .../Protocol/Handlers/Protocol18.cs | 97 ++++++ MinecraftClient/Protocol/IMinecraftCom.cs | 11 + .../Protocol/IMinecraftComHandler.cs | 6 + .../Translations/Translations.Designer.cs | 144 +++++++++ .../Resources/Translations/Translations.resx | 108 +++++++ MinecraftClient/Tui/BookTuiHost.cs | 282 +++++++++++++++++ 15 files changed, 1275 insertions(+), 3 deletions(-) create mode 100644 MinecraftClient/Commands/Book.cs create mode 100644 MinecraftClient/Inventory/BookContent.cs create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs create mode 100644 MinecraftClient/Tui/BookTuiHost.cs diff --git a/MinecraftClient/Commands/Book.cs b/MinecraftClient/Commands/Book.cs new file mode 100644 index 00000000..1362d227 --- /dev/null +++ b/MinecraftClient/Commands/Book.cs @@ -0,0 +1,293 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; +using MinecraftClient.Inventory; +using MinecraftClient.Tui; + +namespace MinecraftClient.Commands +{ + public class Book : Command + { + private const char PageDelimiter = '\f'; + + public override string CmdName => "book"; + public override string CmdUsage => Translations.cmd_book_usage; + public override string CmdDesc => Translations.cmd_book_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source, string.Empty)) + .Then(l => l.Literal("read").Executes(r => GetUsage(r.Source, "read"))) + .Then(l => l.Literal("write").Executes(r => GetUsage(r.Source, "write"))) + .Then(l => l.Literal("edit").Executes(r => GetUsage(r.Source, "edit"))) + .Then(l => l.Literal("sign").Executes(r => GetUsage(r.Source, "sign"))))); + + dispatcher.Register(l => l.Literal(CmdName) + .Then(l => l.Literal("read") + .Executes(r => ReadBook(r.Source, null)) + .Then(l => l.Argument("Page", Arguments.Integer(min: 1)) + .Executes(r => ReadBook(r.Source, Arguments.GetInteger(r, "Page"))))) + .Then(l => l.Literal("write") + .Then(l => l.Literal("text") + .Then(l => l.Argument("Text", Arguments.GreedyString()) + .Executes(r => WriteBook(r.Source, Arguments.GetString(r, "Text"))))) + .Then(l => l.Literal("file") + .Then(l => l.Argument("Path", Arguments.GreedyString()) + .Executes(r => WriteBookFromFile(r.Source, Arguments.GetString(r, "Path")))))) + .Then(l => l.Literal("edit") + .Executes(r => OpenEditor(r.Source)) + .Then(l => l.Literal("page") + .Then(l => l.Argument("Page", Arguments.Integer(min: 1)) + .Then(l => l.Argument("Text", Arguments.GreedyString()) + .Executes(r => EditPage(r.Source, Arguments.GetInteger(r, "Page"), Arguments.GetString(r, "Text")))))) + .Then(l => l.Literal("insert") + .Then(l => l.Argument("Page", Arguments.Integer(min: 1)) + .Then(l => l.Argument("Text", Arguments.GreedyString()) + .Executes(r => InsertPage(r.Source, Arguments.GetInteger(r, "Page"), Arguments.GetString(r, "Text")))))) + .Then(l => l.Literal("delete") + .Then(l => l.Argument("Page", Arguments.Integer(min: 1)) + .Executes(r => DeletePage(r.Source, Arguments.GetInteger(r, "Page")))))) + .Then(l => l.Literal("sign") + .Then(l => l.Argument("Title", Arguments.GreedyString()) + .Executes(r => SignBook(r.Source, Arguments.GetString(r, "Title"))))) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source, string.Empty)) + .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))); + } + + private int GetUsage(CmdResult r, string? cmd) + { + return r.SetAndReturn(cmd switch + { + "read" => Translations.cmd_book_help_read, + "write" => Translations.cmd_book_help_write, + "edit" => Translations.cmd_book_help_edit, + "sign" => Translations.cmd_book_help_sign, + _ => GetCmdDescTranslated() + }); + } + + private int ReadBook(CmdResult r, int? page) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureInventory(r, handler)) + return -1; + + if (!handler.TryGetHeldBookContent(out BookContent content)) + return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_not_holding_book); + + if (page is null && BookTuiHost.TryOpen(handler, BookHand.Main, editable: false)) + return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_tui_opened); + + handler.Log.Info(FormatBook(content, page)); + return r.SetAndReturn(CmdResult.Status.Done); + } + + private int OpenEditor(CmdResult r) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out _)) + return -1; + + return BookTuiHost.TryOpen(handler, BookHand.Main, editable: true) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_tui_opened) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_tui_required); + } + + private int WriteBook(CmdResult r, string text) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out _)) + return -1; + + IReadOnlyList pages = SplitPages(text); + if (!Validate(r, handler, pages, title: null)) + return -1; + + return handler.SendBookEdit(pages) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_write_sent) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_write_failed); + } + + private int WriteBookFromFile(CmdResult r, string path) + { + if (!File.Exists(path)) + return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_file_not_found, path)); + + return WriteBook(r, File.ReadAllText(path, Encoding.UTF8)); + } + + private int EditPage(CmdResult r, int page, string text) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out BookContent content)) + return -1; + + List pages = content.Pages.ToList(); + if (page > pages.Count) + return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_page_out_of_range, page, pages.Count)); + + pages[page - 1] = DecodeInlineText(text); + if (!Validate(r, handler, pages, title: null)) + return -1; + + return handler.SendBookEdit(pages) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_edit_sent) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_write_failed); + } + + private int InsertPage(CmdResult r, int page, string text) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out BookContent content)) + return -1; + + List pages = content.Pages.ToList(); + if (page > pages.Count + 1) + return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_page_out_of_range, page, pages.Count)); + + pages.Insert(page - 1, DecodeInlineText(text)); + if (!Validate(r, handler, pages, title: null)) + return -1; + + return handler.SendBookEdit(pages) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_edit_sent) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_write_failed); + } + + private int DeletePage(CmdResult r, int page) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out BookContent content)) + return -1; + + List pages = content.Pages.ToList(); + if (page > pages.Count) + return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_page_out_of_range, page, pages.Count)); + + pages.RemoveAt(page - 1); + if (pages.Count == 0) + pages.Add(string.Empty); + + if (!Validate(r, handler, pages, title: null)) + return -1; + + return handler.SendBookEdit(pages) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_edit_sent) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_write_failed); + } + + private int SignBook(CmdResult r, string title) + { + McClient handler = CmdResult.currentHandler!; + if (!EnsureWritable(r, handler, out BookContent content)) + return -1; + + string normalizedTitle = title.Trim(); + if (!Validate(r, handler, content.Pages, normalizedTitle)) + return -1; + + return handler.SendBookEdit(content.Pages, normalizedTitle) + ? r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_book_sign_sent) + : r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_write_failed); + } + + private static bool EnsureInventory(CmdResult r, McClient handler) + { + if (handler.GetInventoryEnabled()) + return true; + + r.SetAndReturn(CmdResult.Status.FailNeedInventory); + return false; + } + + private static bool EnsureWritable(CmdResult r, McClient handler, out BookContent content) + { + content = BookContent.EmptyWritable; + if (!EnsureInventory(r, handler)) + return false; + + Item? item = handler.GetHeldBook(); + if (!BookContentHelper.IsWritableBook(item)) + { + r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_not_holding_writable); + return false; + } + + return BookContentHelper.TryRead(item, out content); + } + + private static IReadOnlyList SplitPages(string text) + { + return BookContentHelper.NormalizePages(DecodeInlineText(text).Split(PageDelimiter)); + } + + private static string DecodeInlineText(string text) + { + return text.Replace("\\f", PageDelimiter.ToString(), StringComparison.Ordinal) + .Replace("\\n", "\n", StringComparison.Ordinal); + } + + private static bool Validate(CmdResult r, McClient handler, IReadOnlyList pages, string? title) + { + BookLimits limits = BookLimits.ForProtocol(handler.GetProtocolVersion()); + + if (pages.Count > limits.MaxPages) + { + r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_too_many_pages, pages.Count, limits.MaxPages)); + return false; + } + + for (int i = 0; i < pages.Count; i++) + { + if (pages[i].Length > limits.MaxPageLength) + { + r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_page_too_long, i + 1, pages[i].Length, limits.MaxPageLength)); + return false; + } + } + + if (title is not null && (title.Length == 0 || title.Length > limits.MaxTitleLength)) + { + r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_book_title_invalid, limits.MaxTitleLength)); + return false; + } + + return true; + } + + private static string FormatBook(BookContent content, int? page) + { + StringBuilder sb = new(); + sb.AppendLine(content.IsSigned + ? string.Format(Translations.cmd_book_header_signed, content.Title ?? string.Empty, content.Author ?? string.Empty) + : Translations.cmd_book_header_writable); + + if (page is not null) + { + int index = page.Value - 1; + if (index < 0 || index >= content.Pages.Count) + return string.Format(Translations.cmd_book_page_out_of_range, page.Value, content.Pages.Count); + + sb.AppendLine(string.Format(Translations.cmd_book_page_header, page.Value, content.Pages.Count)); + sb.Append(content.Pages[index]); + return sb.ToString(); + } + + for (int i = 0; i < content.Pages.Count; i++) + { + sb.AppendLine(string.Format(Translations.cmd_book_page_header, i + 1, content.Pages.Count)); + sb.AppendLine(content.Pages[i]); + } + + return sb.ToString().TrimEnd(); + } + } +} diff --git a/MinecraftClient/Inventory/BookContent.cs b/MinecraftClient/Inventory/BookContent.cs new file mode 100644 index 00000000..239e3813 --- /dev/null +++ b/MinecraftClient/Inventory/BookContent.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using MinecraftClient.Protocol.Handlers; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Inventory; + +public enum BookHand +{ + Main = 0, + Off = 1 +} + +public sealed record BookLimits(int MaxPages, int MaxPageLength, int MaxTitleLength) +{ + public static BookLimits ForProtocol(int protocolVersion) + { + int maxPageLength = protocolVersion switch + { + >= Protocol18Handler.MC_1_21_2_Version => 1024, + >= Protocol18Handler.MC_1_17_Version => 8192, + _ => 32767 + }; + + int maxTitleLength = protocolVersion switch + { + >= Protocol18Handler.MC_1_21_2_Version => 32, + >= Protocol18Handler.MC_1_17_Version => 128, + _ => 16 + }; + + return new BookLimits(100, maxPageLength, maxTitleLength); + } +} + +public sealed record BookContent( + IReadOnlyList Pages, + string? Title, + string? Author, + int Generation, + bool IsSigned) +{ + public static BookContent EmptyWritable { get; } = new([string.Empty], null, null, 0, false); +} + +public static class BookContentHelper +{ + public static bool IsBook(Item? item) => item?.Type is ItemType.WritableBook or ItemType.WrittenBook; + + public static bool IsWritableBook(Item? item) => item?.Type == ItemType.WritableBook; + + public static bool TryRead(Item? item, out BookContent content) + { + content = BookContent.EmptyWritable; + + if (item is null || item.IsEmpty) + return false; + + return item.Type switch + { + ItemType.WritableBook => TryReadWritable(item, out content), + ItemType.WrittenBook => TryReadWritten(item, out content), + _ => false + }; + } + + public static Item CreateWritablePayload(Item currentBook, IReadOnlyList pages) + { + return new Item(ItemType.WritableBook, 1, currentBook.Data, new Dictionary + { + ["pages"] = pages.Cast().ToArray() + }); + } + + public static Item CreateWrittenPayload(Item currentBook, IReadOnlyList pages, string title, string author, bool encodePagesAsJson) + { + object[] encodedPages = pages + .Select(page => encodePagesAsJson ? ToJsonTextComponent(page) : page) + .Cast() + .ToArray(); + + return new Item(ItemType.WrittenBook, 1, currentBook.Data, new Dictionary + { + ["author"] = author, + ["title"] = title, + ["pages"] = encodedPages + }); + } + + public static IReadOnlyList NormalizePages(IEnumerable pages) + { + string[] normalized = pages.Select(page => page ?? string.Empty).ToArray(); + return normalized.Length == 0 ? [string.Empty] : normalized; + } + + private static bool TryReadWritable(Item item, out BookContent content) + { + if (item.Components is not null) + { + var component = item.Components.OfType().FirstOrDefault(); + if (component is not null) + { + content = new BookContent( + NormalizePages(component.Pages.Select(page => page.RawContent)), + null, + null, + 0, + IsSigned: false); + return true; + } + } + + content = new BookContent(ReadStringList(item.NBT, "pages", parseJson: false), null, null, 0, IsSigned: false); + return true; + } + + private static bool TryReadWritten(Item item, out BookContent content) + { + if (item.Components is not null) + { + var component = item.Components.OfType().FirstOrDefault(); + if (component is not null) + { + content = new BookContent( + NormalizePages(component.Pages.Select(page => page.RawContent)), + component.RawTitle, + component.Author, + component.Generation, + IsSigned: true); + return true; + } + } + + string? title = ReadString(item.NBT, "title"); + string? author = ReadString(item.NBT, "author"); + int generation = ReadInt(item.NBT, "generation"); + content = new BookContent(ReadStringList(item.NBT, "pages", parseJson: true), title, author, generation, IsSigned: true); + return true; + } + + private static IReadOnlyList ReadStringList(Dictionary? nbt, string key, bool parseJson) + { + if (nbt is null || !nbt.TryGetValue(key, out object? value) || value is not object[] values) + return [string.Empty]; + + string[] pages = values + .Select(value => value?.ToString() ?? string.Empty) + .Select(value => parseJson ? ChatParser.ParseText(value) : value) + .ToArray(); + + return pages.Length == 0 ? [string.Empty] : pages; + } + + private static string? ReadString(Dictionary? nbt, string key) + { + return nbt is not null && nbt.TryGetValue(key, out object? value) + ? value?.ToString() + : null; + } + + private static int ReadInt(Dictionary? nbt, string key) + { + if (nbt is null || !nbt.TryGetValue(key, out object? value) || value is null) + return 0; + + return value switch + { + int i => i, + short s => s, + byte b => b, + _ when int.TryParse(value.ToString(), out int parsed) => parsed, + _ => 0 + }; + } + + private static string ToJsonTextComponent(string text) + { + return JsonSerializer.Serialize(new Dictionary { ["text"] = text }); + } +} diff --git a/MinecraftClient/Inventory/Item.cs b/MinecraftClient/Inventory/Item.cs index e794e205..69d175fb 100644 --- a/MinecraftClient/Inventory/Item.cs +++ b/MinecraftClient/Inventory/Item.cs @@ -272,4 +272,4 @@ namespace MinecraftClient.Inventory return sb.ToString(); } } -} \ No newline at end of file +} diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs new file mode 100644 index 00000000..3e8e1494 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + /// + /// Minimal flattened item palette for 1.13-1.14 book handling. + /// + public class ItemPalette113 : ItemPalette + { + private static readonly Dictionary mappings = new() + { + [0] = ItemType.Air, + [687] = ItemType.WritableBook, + [688] = ItemType.WrittenBook + }; + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs new file mode 100644 index 00000000..24da1d8f --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + /// + /// Minimal flattened item palette for 1.13.2 book handling. + /// + public class ItemPalette1132 : ItemPalette + { + private static readonly Dictionary mappings = new() + { + [0] = ItemType.Air, + [692] = ItemType.WritableBook, + [693] = ItemType.WrittenBook + }; + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs new file mode 100644 index 00000000..c4c02a09 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + /// + /// Minimal flattened item palette for 1.14 book handling. + /// + public class ItemPalette114 : ItemPalette + { + private static readonly Dictionary mappings = new() + { + [0] = ItemType.Air, + [757] = ItemType.WritableBook, + [758] = ItemType.WrittenBook + }; + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 3ba651a5..136fe224 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1850,6 +1850,72 @@ namespace MinecraftClient return handler.SendPluginChannelPacket(channel, data); } + public Item? GetHeldBook(BookHand hand = BookHand.Main) + { + if (InvokeRequired) + return InvokeOnMainThread(() => GetHeldBook(hand)); + + if (!inventoryHandlingEnabled || !inventories.TryGetValue(0, out Container? inventory)) + return null; + + int slot = hand == BookHand.Off ? 45 : 36 + CurrentSlot; + return inventory.Items.TryGetValue(slot, out Item? item) ? item : null; + } + + public bool TryGetHeldBookContent(out BookContent content, BookHand hand = BookHand.Main) + { + if (InvokeRequired) + { + (bool ok, BookContent value) = InvokeOnMainThread(() => + { + bool ok = TryGetHeldBookContent(out BookContent value, hand); + return (ok, value); + }); + content = value; + return ok; + } + + return BookContentHelper.TryRead(GetHeldBook(hand), out content); + } + + public bool SendBookEdit(IReadOnlyList pages, string? title = null) + { + if (InvokeRequired) + return InvokeOnMainThread(() => SendBookEdit(pages, title)); + + Item? currentBook = GetHeldBook(BookHand.Main); + if (!BookContentHelper.IsWritableBook(currentBook)) + return false; + + IReadOnlyList normalizedPages = BookContentHelper.NormalizePages(pages); + bool sent = handler.SendEditBook(currentBook!, normalizedPages, title, username, CurrentSlot); + if (sent && GetProtocolVersion() < Protocol18Handler.MC_1_17_Version) + SetHeldBook(BookHand.Main, CreateLocalBookResult(currentBook!, normalizedPages, title)); + + return sent; + } + + private Item CreateLocalBookResult(Item currentBook, IReadOnlyList pages, string? title) + { + return title is null + ? BookContentHelper.CreateWritablePayload(currentBook, pages) + : BookContentHelper.CreateWrittenPayload( + currentBook, + pages, + title, + username, + encodePagesAsJson: GetProtocolVersion() < Protocol18Handler.MC_1_9_Version); + } + + private void SetHeldBook(BookHand hand, Item item) + { + if (!inventoryHandlingEnabled || !inventories.TryGetValue(0, out Container? inventory)) + return; + + int slot = hand == BookHand.Off ? 45 : 36 + CurrentSlot; + inventory.Items[slot] = item; + } + /// /// Send the Entity Action packet with the Specified ID /// @@ -3817,6 +3883,17 @@ namespace MinecraftClient } } + public void OnBookOpen(int hand) + { + if (InvokeRequired) + { + InvokeOnMainThread(() => OnBookOpen(hand)); + return; + } + + Tui.BookTuiHost.OpenFromServer(this, hand == (int)BookHand.Off ? BookHand.Off : BookHand.Main); + } + /// /// Called when an entity spawned /// diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index bdbdecea..36b26917 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -514,7 +514,7 @@ namespace MinecraftClient.Protocol.Handlers var type = itemPalette.FromId(itemId); itemCount = ReadNextByte(cache); nbt = ReadNextNbt(cache); - return new Item(type, itemCount, nbt); + return new Item(type, itemCount, itemId, nbt); } case >= Protocol18Handler.MC_1_13_Version: { @@ -526,7 +526,7 @@ namespace MinecraftClient.Protocol.Handlers var type = itemPalette.FromId(itemId); itemCount = ReadNextByte(cache); nbt = ReadNextNbt(cache); - return new Item(type, itemCount, nbt); + return new Item(type, itemCount, itemId, nbt); } default: { diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 6777200d..bb0fb863 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -816,6 +816,11 @@ namespace MinecraftClient.Protocol.Handlers return false; //MC 1.8-1.12.1 recipe book not supported } + public bool SendEditBook(Item currentBook, IReadOnlyList 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 diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 50e7b91a..8a7dbd67 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -241,6 +241,9 @@ namespace MinecraftClient.Protocol.Handlers >= MC_1_16_2_Version => new ItemPalette1162(), >= MC_1_16_1_Version => new ItemPalette1161(), >= MC_1_15_Version => new ItemPalette115(), + >= MC_1_14_Version => new ItemPalette114(), + >= MC_1_13_2_Version => new ItemPalette1132(), + >= MC_1_13_Version => new ItemPalette113(), >= MC_1_12_Version => new ItemPalette112(), >= MC_1_11_Version => new ItemPalette111(), >= MC_1_10_Version => new ItemPalette110(), @@ -2313,8 +2316,13 @@ namespace MinecraftClient.Protocol.Handlers // Length is unneeded as the whole remaining packetData is the entire payload of the packet. if (protocolVersion < MC_1_8_Version) pForge.ReadNextVarShort(packetData); + if (IsOpenBookPluginChannel(channel)) + handler.OnBookOpen(ReadBookHand(new Queue(packetData))); handler.OnPluginChannelMessage(channel, packetData.ToArray()); return pForge.HandlePluginMessage(channel, packetData, ref currentDimension); + case PacketTypesIn.OpenBook: + handler.OnBookOpen(ReadBookHand(packetData)); + break; case PacketTypesIn.Disconnect: handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, dataTypes.ReadNextChat(packetData)); @@ -2984,6 +2992,9 @@ namespace MinecraftClient.Protocol.Handlers soundName = null; } + if (protocolVersion < MC_1_19_Version && packetData.Count < 21) + break; + int category = dataTypes.ReadNextVarInt(packetData); double x = dataTypes.ReadNextInt(packetData) / 8.0D; double y = dataTypes.ReadNextInt(packetData) / 8.0D; @@ -5279,6 +5290,18 @@ namespace MinecraftClient.Protocol.Handlers } } + private bool IsOpenBookPluginChannel(string channel) + { + return protocolVersion < MC_1_13_Version + ? string.Equals(channel, "MC|BOpen", StringComparison.Ordinal) + : string.Equals(channel, "minecraft:book_open", StringComparison.Ordinal); + } + + private int ReadBookHand(Queue packetData) + { + return packetData.Count > 0 ? dataTypes.ReadNextVarInt(packetData) : (int)BookHand.Main; + } + /// /// Send a Login Plugin Response packet (0x02) /// @@ -5881,6 +5904,80 @@ namespace MinecraftClient.Protocol.Handlers } } + public bool SendEditBook(Item currentBook, IReadOnlyList pages, string? title, string author, int selectedHotbarSlot) + { + try + { + if (protocolVersion < MC_1_8_Version) + return false; + + bool signing = title is not null; + IReadOnlyList normalizedPages = BookContentHelper.NormalizePages(pages); + + if (protocolVersion < MC_1_13_Version) + { + Item payload = signing + ? BookContentHelper.CreateWrittenPayload( + currentBook, + normalizedPages, + title ?? string.Empty, + author, + encodePagesAsJson: protocolVersion < MC_1_9_Version) + : BookContentHelper.CreateWritablePayload(currentBook, normalizedPages); + + byte[] payloadData = dataTypes.GetItemSlot(payload, itemPalette); + if (payloadData.Length > 32767) + return false; + + return SendPluginChannelPacket(signing ? "MC|BSign" : "MC|BEdit", payloadData); + } + + if (protocolVersion < MC_1_17_Version) + { + Item payload = signing + ? BookContentHelper.CreateWrittenPayload(currentBook, normalizedPages, title ?? string.Empty, author, encodePagesAsJson: false) + : BookContentHelper.CreateWritablePayload(currentBook, normalizedPages); + + List packet = new(); + packet.AddRange(dataTypes.GetItemSlot(payload, itemPalette)); + packet.AddRange(dataTypes.GetBool(signing)); + + if (protocolVersion >= MC_1_16_5_Version) + packet.AddRange(DataTypes.GetVarInt(selectedHotbarSlot)); + else if (protocolVersion >= MC_1_13_2_Version) + packet.AddRange(DataTypes.GetVarInt((int)BookHand.Main)); + + SendPacket(PacketTypesOut.EditBook, packet); + return true; + } + + List modernPacket = new(); + modernPacket.AddRange(DataTypes.GetVarInt(selectedHotbarSlot)); + modernPacket.AddRange(DataTypes.GetVarInt(normalizedPages.Count)); + foreach (string page in normalizedPages) + modernPacket.AddRange(dataTypes.GetString(page)); + + modernPacket.AddRange(dataTypes.GetBool(signing)); + if (signing) + modernPacket.AddRange(dataTypes.GetString(title ?? string.Empty)); + + SendPacket(PacketTypesOut.EditBook, modernPacket); + return true; + } + catch (SocketException) + { + return false; + } + catch (System.IO.IOException) + { + return false; + } + catch (ObjectDisposedException) + { + return false; + } + } + public bool SendAnimation(int animation, int playerId) { try diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs index 96b261b1..df0a37fe 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -199,6 +199,17 @@ namespace MinecraftClient.Protocol /// True if packet was successfully sent bool SendPlaceRecipe(int windowId, string recipeId, bool makeAll); + /// + /// Send a book edit/sign packet for the currently held writable book. + /// + /// Current held writable book + /// Book pages + /// Title when signing, otherwise null + /// Current player name when signing + /// Selected hotbar slot, 0-8 + /// True if packet was successfully sent + bool SendEditBook(Item currentBook, IReadOnlyList pages, string? title, string author, int selectedHotbarSlot); + /// /// Plays animation /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 5c100981..be406ef8 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -224,6 +224,12 @@ namespace MinecraftClient.Protocol /// The data from the channel void OnPluginChannelMessage(string channel, byte[] data); + /// + /// Called when the server asks the client to open a book UI. + /// + /// Book hand, 0 main hand, 1 off hand. + void OnBookOpen(int hand); + /// /// Called when an entity has spawned /// diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index b6e454cd..bccd0a57 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -7552,5 +7552,149 @@ namespace MinecraftClient { return ResourceManager.GetString("cmd.achievement.entry", resourceCulture); } } + internal static string cmd_book_usage { + get { return ResourceManager.GetString("cmd.book.usage", resourceCulture); } + } + + internal static string cmd_book_desc { + get { return ResourceManager.GetString("cmd.book.desc", resourceCulture); } + } + + internal static string cmd_book_help_read { + get { return ResourceManager.GetString("cmd.book.help_read", resourceCulture); } + } + + internal static string cmd_book_help_write { + get { return ResourceManager.GetString("cmd.book.help_write", resourceCulture); } + } + + internal static string cmd_book_help_edit { + get { return ResourceManager.GetString("cmd.book.help_edit", resourceCulture); } + } + + internal static string cmd_book_help_sign { + get { return ResourceManager.GetString("cmd.book.help_sign", resourceCulture); } + } + + internal static string cmd_book_not_holding_book { + get { return ResourceManager.GetString("cmd.book.not_holding_book", resourceCulture); } + } + + internal static string cmd_book_not_holding_writable { + get { return ResourceManager.GetString("cmd.book.not_holding_writable", resourceCulture); } + } + + internal static string cmd_book_tui_opened { + get { return ResourceManager.GetString("cmd.book.tui_opened", resourceCulture); } + } + + internal static string cmd_book_tui_required { + get { return ResourceManager.GetString("cmd.book.tui_required", resourceCulture); } + } + + internal static string cmd_book_write_sent { + get { return ResourceManager.GetString("cmd.book.write_sent", resourceCulture); } + } + + internal static string cmd_book_edit_sent { + get { return ResourceManager.GetString("cmd.book.edit_sent", resourceCulture); } + } + + internal static string cmd_book_sign_sent { + get { return ResourceManager.GetString("cmd.book.sign_sent", resourceCulture); } + } + + internal static string cmd_book_write_failed { + get { return ResourceManager.GetString("cmd.book.write_failed", resourceCulture); } + } + + internal static string cmd_book_file_not_found { + get { return ResourceManager.GetString("cmd.book.file_not_found", resourceCulture); } + } + + internal static string cmd_book_page_out_of_range { + get { return ResourceManager.GetString("cmd.book.page_out_of_range", resourceCulture); } + } + + internal static string cmd_book_too_many_pages { + get { return ResourceManager.GetString("cmd.book.too_many_pages", resourceCulture); } + } + + internal static string cmd_book_page_too_long { + get { return ResourceManager.GetString("cmd.book.page_too_long", resourceCulture); } + } + + internal static string cmd_book_title_invalid { + get { return ResourceManager.GetString("cmd.book.title_invalid", resourceCulture); } + } + + internal static string cmd_book_header_signed { + get { return ResourceManager.GetString("cmd.book.header_signed", resourceCulture); } + } + + internal static string cmd_book_header_writable { + get { return ResourceManager.GetString("cmd.book.header_writable", resourceCulture); } + } + + internal static string cmd_book_page_header { + get { return ResourceManager.GetString("cmd.book.page_header", resourceCulture); } + } + + internal static string tui_book_title_watermark { + get { return ResourceManager.GetString("tui.book.title_watermark", resourceCulture); } + } + + internal static string tui_book_prev { + get { return ResourceManager.GetString("tui.book.prev", resourceCulture); } + } + + internal static string tui_book_next { + get { return ResourceManager.GetString("tui.book.next", resourceCulture); } + } + + internal static string tui_book_insert { + get { return ResourceManager.GetString("tui.book.insert", resourceCulture); } + } + + internal static string tui_book_delete { + get { return ResourceManager.GetString("tui.book.delete", resourceCulture); } + } + + internal static string tui_book_save { + get { return ResourceManager.GetString("tui.book.save", resourceCulture); } + } + + internal static string tui_book_sign { + get { return ResourceManager.GetString("tui.book.sign", resourceCulture); } + } + + internal static string tui_book_close { + get { return ResourceManager.GetString("tui.book.close", resourceCulture); } + } + + internal static string tui_book_saved { + get { return ResourceManager.GetString("tui.book.saved", resourceCulture); } + } + + internal static string tui_book_save_failed { + get { return ResourceManager.GetString("tui.book.save_failed", resourceCulture); } + } + + internal static string tui_book_signed { + get { return ResourceManager.GetString("tui.book.signed", resourceCulture); } + } + + internal static string tui_book_page_header { + get { return ResourceManager.GetString("tui.book.page_header", resourceCulture); } + } + + internal static string tui_book_editing { + get { return ResourceManager.GetString("tui.book.editing", resourceCulture); } + } + + internal static string tui_book_reading { + get { return ResourceManager.GetString("tui.book.reading", resourceCulture); } + } + } } diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 2e9da34a..aa167797 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2659,4 +2659,112 @@ see item details. {0} {1} [{2}] + + book <read|write|edit|sign> + + + read, write, edit, and sign the book held in your main hand. + + + /book read [page] + + + /book write text <text> or /book write file <path>. Use \n for line breaks and \f for page breaks. + + + /book edit, /book edit page <page> <text>, /book edit insert <page> <text>, or /book edit delete <page>. + + + /book sign <title> + + + You are not holding a book. + + + You must hold a writable book in your main hand. + + + Book TUI opened. + + + The book editor is only available in TUI mode. + + + Book write packet sent. + + + Book edit packet sent. + + + Book sign packet sent. + + + Book packet could not be sent. + + + Book file not found: {0} + + + Page {0} is outside the current page range 1-{1}. + + + Book has {0} pages, but this version supports at most {1} pages. + + + Page {0} has {1} characters, but this version supports at most {2} characters per page. + + + Book title must be 1-{0} characters. + + + Written book: {0} by {1} + + + Writable book + + + Page {0}/{1} + + + Title + + + Prev + + + Next + + + Insert + + + Delete + + + Save + + + Sign + + + Close + + + Saved. + + + Book packet could not be sent. + + + Signed. + + + Book page {0}/{1} + + + Editing writable book. + + + Reading book. + diff --git a/MinecraftClient/Tui/BookTuiHost.cs b/MinecraftClient/Tui/BookTuiHost.cs new file mode 100644 index 00000000..eac8c2b0 --- /dev/null +++ b/MinecraftClient/Tui/BookTuiHost.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Layout; +using Avalonia.Media; +using Avalonia.Threading; +using MinecraftClient.Inventory; + +namespace MinecraftClient.Tui; + +public static class BookTuiHost +{ + private static volatile bool isRunning; + + public static bool TryOpen(McClient handler, BookHand hand, bool editable) + { + if (ConsoleIO.Backend is not TuiConsoleBackend) + return false; + + Open(handler, hand, editable); + return true; + } + + public static void OpenFromServer(McClient handler, BookHand hand) + { + if (ConsoleIO.Backend is TuiConsoleBackend) + Open(handler, hand, editable: BookContentHelper.IsWritableBook(handler.GetHeldBook(hand))); + } + + private static void Open(McClient handler, BookHand hand, bool editable) + { + Dispatcher.UIThread.Post(() => + { + if (isRunning) + return; + + MainTuiView? view = TuiConsoleBackend.Instance?.GetView(); + if (view is null) + return; + + if (!handler.TryGetHeldBookContent(out BookContent content, hand)) + return; + + isRunning = true; + var bookView = new BookView(handler, content, editable && !content.IsSigned); + view.ShowOverlay(bookView, () => isRunning = false); + }); + } +} + +internal sealed class BookView : UserControl +{ + private readonly McClient handler; + private readonly bool editable; + private readonly List pages; + private readonly TextBlock header; + private readonly TextBlock status; + private readonly TextBox pageText; + private readonly TextBox titleText; + private int pageIndex; + + public BookView(McClient handler, BookContent content, bool editable) + { + this.handler = handler; + this.editable = editable; + pages = content.Pages.ToList(); + if (pages.Count == 0) + pages.Add(string.Empty); + + Focusable = true; + Background = Brushes.Black; + + header = new TextBlock + { + Foreground = Brushes.Yellow, + Margin = new Thickness(1, 0), + TextWrapping = TextWrapping.Wrap + }; + + status = new TextBlock + { + Foreground = Brushes.Gray, + Margin = new Thickness(1, 0), + TextWrapping = TextWrapping.Wrap + }; + + pageText = new TextBox + { + AcceptsReturn = true, + TextWrapping = TextWrapping.Wrap, + IsReadOnly = !editable, + Foreground = Brushes.White, + Background = Brushes.Black, + BorderBrush = Brushes.Gray, + MinHeight = 12, + Margin = new Thickness(1) + }; + pageText.TextChanged += (_, _) => + { + if (editable && pageIndex >= 0 && pageIndex < pages.Count) + pages[pageIndex] = pageText.Text ?? string.Empty; + }; + + titleText = new TextBox + { + Watermark = Translations.tui_book_title_watermark, + IsVisible = editable, + Foreground = Brushes.White, + Background = Brushes.Black, + BorderBrush = Brushes.Gray, + Margin = new Thickness(1) + }; + + var controls = new StackPanel + { + Orientation = Orientation.Horizontal, + Spacing = 1, + Margin = new Thickness(1), + Children = + { + Button(Translations.tui_book_prev, (_, _) => MovePage(-1)), + Button(Translations.tui_book_next, (_, _) => MovePage(1)), + Button(Translations.tui_book_insert, (_, _) => InsertPage(), editable), + Button(Translations.tui_book_delete, (_, _) => DeletePage(), editable), + Button(Translations.tui_book_save, (_, _) => Save(), editable), + Button(Translations.tui_book_sign, (_, _) => Sign(), editable), + Button(Translations.tui_book_close, (_, _) => Close()) + } + }; + + var panel = new DockPanel + { + Background = Brushes.Black, + Children = + { + DockTo(header, Dock.Top), + DockTo(status, Dock.Bottom), + DockTo(controls, Dock.Bottom), + DockTo(titleText, Dock.Bottom), + pageText + } + }; + + Content = panel; + Refresh(); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.Key == Key.PageUp) + { + MovePage(-1); + e.Handled = true; + return; + } + + if (e.Key == Key.PageDown) + { + MovePage(1); + e.Handled = true; + return; + } + + base.OnKeyDown(e); + } + + private static Control DockTo(Control control, Dock dock) + { + DockPanel.SetDock(control, dock); + return control; + } + + private static Button Button(string text, EventHandler handler, bool enabled = true) + { + var button = new Button + { + Content = text, + IsEnabled = enabled, + Padding = new Thickness(1, 0), + Margin = new Thickness(0) + }; + button.Click += handler; + return button; + } + + private void MovePage(int delta) + { + pageIndex = Math.Clamp(pageIndex + delta, 0, pages.Count - 1); + Refresh(); + } + + private void InsertPage() + { + pages.Insert(pageIndex + 1, string.Empty); + pageIndex++; + Refresh(); + } + + private void DeletePage() + { + if (pages.Count == 1) + pages[0] = string.Empty; + else + { + pages.RemoveAt(pageIndex); + pageIndex = Math.Clamp(pageIndex, 0, pages.Count - 1); + } + Refresh(); + } + + private void Save() + { + if (!Validate(out string error)) + { + status.Text = error; + return; + } + + status.Text = handler.SendBookEdit(pages) + ? Translations.tui_book_saved + : Translations.tui_book_save_failed; + } + + private void Sign() + { + string title = (titleText.Text ?? string.Empty).Trim(); + if (!Validate(out string error, title)) + { + status.Text = error; + return; + } + + status.Text = handler.SendBookEdit(pages, title) + ? Translations.tui_book_signed + : Translations.tui_book_save_failed; + } + + private bool Validate(out string error, string? title = null) + { + BookLimits limits = BookLimits.ForProtocol(handler.GetProtocolVersion()); + error = string.Empty; + + if (pages.Count > limits.MaxPages) + { + error = string.Format(Translations.cmd_book_too_many_pages, pages.Count, limits.MaxPages); + return false; + } + + for (int i = 0; i < pages.Count; i++) + { + if (pages[i].Length > limits.MaxPageLength) + { + error = string.Format(Translations.cmd_book_page_too_long, i + 1, pages[i].Length, limits.MaxPageLength); + return false; + } + } + + if (title is not null && (title.Length == 0 || title.Length > limits.MaxTitleLength)) + { + error = string.Format(Translations.cmd_book_title_invalid, limits.MaxTitleLength); + return false; + } + + return true; + } + + private void Close() + { + TuiConsoleBackend.Instance?.GetView()?.HideOverlay(); + } + + private void Refresh() + { + pageText.Text = pages[pageIndex]; + header.Text = string.Format(Translations.tui_book_page_header, pageIndex + 1, pages.Count); + status.Text = editable ? Translations.tui_book_editing : Translations.tui_book_reading; + pageText.Focus(); + } +} From 8e31a37ea9659f900995a84fdd696ff009405809 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 2 May 2026 18:51:40 +0200 Subject: [PATCH 2/4] Document book command support Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/guide/README.md | 2 + docs/guide/usage.md | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/docs/guide/README.md b/docs/guide/README.md index b645b958..a5fd572d 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -71,6 +71,8 @@ It was originally made by [ORelio](https://github.com/ORelio) in 2012 on the [Mi - [Inventory Handling](usage.md#inventory) +- [Book Support](usage.md#book) + - [Terrain Traversing](usage.md#move) - Entity Handling diff --git a/docs/guide/usage.md b/docs/guide/usage.md index d6dcfaeb..6aa10b6a 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -267,6 +267,117 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q +
+book + +

Note

+ +**You need to have [Inventory Handling](configuration.md#inventoryhandling) enabled in order for this to work.** + +
+ +- **Description:** + + Read the book in your main hand, or edit it if it is a writable book. + + In TUI mode, `/book read` opens a page viewer instead of printing the whole book to chat. The same viewer also opens automatically when the server tells the client to open a book. + + If you are holding a writable book, you can replace all pages, update one page, insert a page, delete a page, and sign the finished book. + +- **Usage:** + + Read the current book or a single page: + + ``` + /book read [page] + ``` + + Replace the whole writable book from inline text or a file: + + ``` + /book write text + /book write file + ``` + + Open the TUI editor or edit specific pages from the command line: + + ``` + /book edit + /book edit page + /book edit insert + /book edit delete + ``` + + Sign the writable book in your main hand: + + ``` + /book sign + ``` + +- **Notes:** + + `read` works with a writable book or a written book in your main hand. + + `write`, `edit`, and `sign` require a writable book in your main hand. + + Use `\n` for line breaks and `\f` for page breaks when passing inline text. + + MCC checks page count, page length, and title length against the current protocol before sending the packet. + + The interactive editor is only available in TUI mode. + +- **Examples:** + + Read the held book: + + ``` + /book read + ``` + + Show only page 2: + + ``` + /book read 2 + ``` + + Write two pages from the command line: + + ``` + /book write text First page\nSecond line\fSecond page + ``` + + Load the book text from a file: + + ``` + /book write file ./letter.txt + ``` + + Replace page 3: + + ``` + /book edit page 3 Updated text for page three + ``` + + Insert a new page before page 2: + + ``` + /book edit insert 2 This page goes before the old page 2 + ``` + + Delete page 4: + + ``` + /book edit delete 4 + ``` + + Sign the current writable book: + + ``` + /book sign Meeting Notes + ``` + +</details> + <details> <summary><code>bed</code></summary> From 72001554a8bb5cb5eb46b9d16d13563776aa42f8 Mon Sep 17 00:00:00 2001 From: Anon <bgteam@live.com> Date: Sat, 2 May 2026 19:22:08 +0200 Subject: [PATCH 3/4] Complete 1.13-1.14 item palettes --- .../Inventory/ItemPalettes/ItemPalette113.cs | 797 +++++++++++++++- .../Inventory/ItemPalettes/ItemPalette1132.cs | 802 +++++++++++++++- .../Inventory/ItemPalettes/ItemPalette114.cs | 889 +++++++++++++++++- .../Protocol/Handlers/Protocol18.cs | 6 +- 4 files changed, 2467 insertions(+), 27 deletions(-) diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs index 3e8e1494..af292fa1 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette113.cs @@ -2,17 +2,798 @@ using System.Collections.Generic; namespace MinecraftClient.Inventory.ItemPalettes { - /// <summary> - /// Minimal flattened item palette for 1.13-1.14 book handling. - /// </summary> public class ItemPalette113 : ItemPalette { - private static readonly Dictionary<int, ItemType> mappings = new() + private static readonly Dictionary<int, ItemType> mappings = new(); + + static ItemPalette113() { - [0] = ItemType.Air, - [687] = ItemType.WritableBook, - [688] = ItemType.WrittenBook - }; + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.GrassBlock; + mappings[9] = ItemType.Dirt; + mappings[10] = ItemType.CoarseDirt; + mappings[11] = ItemType.Podzol; + mappings[12] = ItemType.Cobblestone; + mappings[13] = ItemType.OakPlanks; + mappings[14] = ItemType.SprucePlanks; + mappings[15] = ItemType.BirchPlanks; + mappings[16] = ItemType.JunglePlanks; + mappings[17] = ItemType.AcaciaPlanks; + mappings[18] = ItemType.DarkOakPlanks; + mappings[19] = ItemType.OakSapling; + mappings[20] = ItemType.SpruceSapling; + mappings[21] = ItemType.BirchSapling; + mappings[22] = ItemType.JungleSapling; + mappings[23] = ItemType.AcaciaSapling; + mappings[24] = ItemType.DarkOakSapling; + mappings[25] = ItemType.Bedrock; + mappings[26] = ItemType.Sand; + mappings[27] = ItemType.RedSand; + mappings[28] = ItemType.Gravel; + mappings[29] = ItemType.GoldOre; + mappings[30] = ItemType.IronOre; + mappings[31] = ItemType.CoalOre; + mappings[32] = ItemType.OakLog; + mappings[33] = ItemType.SpruceLog; + mappings[34] = ItemType.BirchLog; + mappings[35] = ItemType.JungleLog; + mappings[36] = ItemType.AcaciaLog; + mappings[37] = ItemType.DarkOakLog; + mappings[38] = ItemType.StrippedOakLog; + mappings[39] = ItemType.StrippedSpruceLog; + mappings[40] = ItemType.StrippedBirchLog; + mappings[41] = ItemType.StrippedJungleLog; + mappings[42] = ItemType.StrippedAcaciaLog; + mappings[43] = ItemType.StrippedDarkOakLog; + mappings[44] = ItemType.StrippedOakWood; + mappings[45] = ItemType.StrippedSpruceWood; + mappings[46] = ItemType.StrippedBirchWood; + mappings[47] = ItemType.StrippedJungleWood; + mappings[48] = ItemType.StrippedAcaciaWood; + mappings[49] = ItemType.StrippedDarkOakWood; + mappings[50] = ItemType.OakWood; + mappings[51] = ItemType.SpruceWood; + mappings[52] = ItemType.BirchWood; + mappings[53] = ItemType.JungleWood; + mappings[54] = ItemType.AcaciaWood; + mappings[55] = ItemType.DarkOakWood; + mappings[56] = ItemType.OakLeaves; + mappings[57] = ItemType.SpruceLeaves; + mappings[58] = ItemType.BirchLeaves; + mappings[59] = ItemType.JungleLeaves; + mappings[60] = ItemType.AcaciaLeaves; + mappings[61] = ItemType.DarkOakLeaves; + mappings[62] = ItemType.Sponge; + mappings[63] = ItemType.WetSponge; + mappings[64] = ItemType.Glass; + mappings[65] = ItemType.LapisOre; + mappings[66] = ItemType.LapisBlock; + mappings[67] = ItemType.Dispenser; + mappings[68] = ItemType.Sandstone; + mappings[69] = ItemType.ChiseledSandstone; + mappings[70] = ItemType.CutSandstone; + mappings[71] = ItemType.NoteBlock; + mappings[72] = ItemType.PoweredRail; + mappings[73] = ItemType.DetectorRail; + mappings[74] = ItemType.StickyPiston; + mappings[75] = ItemType.Cobweb; + mappings[76] = ItemType.ShortGrass; + mappings[77] = ItemType.Fern; + mappings[78] = ItemType.DeadBush; + mappings[79] = ItemType.Seagrass; + mappings[80] = ItemType.SeaPickle; + mappings[81] = ItemType.Piston; + mappings[82] = ItemType.WhiteWool; + mappings[83] = ItemType.OrangeWool; + mappings[84] = ItemType.MagentaWool; + mappings[85] = ItemType.LightBlueWool; + mappings[86] = ItemType.YellowWool; + mappings[87] = ItemType.LimeWool; + mappings[88] = ItemType.PinkWool; + mappings[89] = ItemType.GrayWool; + mappings[90] = ItemType.LightGrayWool; + mappings[91] = ItemType.CyanWool; + mappings[92] = ItemType.PurpleWool; + mappings[93] = ItemType.BlueWool; + mappings[94] = ItemType.BrownWool; + mappings[95] = ItemType.GreenWool; + mappings[96] = ItemType.RedWool; + mappings[97] = ItemType.BlackWool; + mappings[98] = ItemType.Dandelion; + mappings[99] = ItemType.Poppy; + mappings[100] = ItemType.BlueOrchid; + mappings[101] = ItemType.Allium; + mappings[102] = ItemType.AzureBluet; + mappings[103] = ItemType.RedTulip; + mappings[104] = ItemType.OrangeTulip; + mappings[105] = ItemType.WhiteTulip; + mappings[106] = ItemType.PinkTulip; + mappings[107] = ItemType.OxeyeDaisy; + mappings[108] = ItemType.BrownMushroom; + mappings[109] = ItemType.RedMushroom; + mappings[110] = ItemType.GoldBlock; + mappings[111] = ItemType.IronBlock; + mappings[112] = ItemType.OakSlab; + mappings[113] = ItemType.SpruceSlab; + mappings[114] = ItemType.BirchSlab; + mappings[115] = ItemType.JungleSlab; + mappings[116] = ItemType.AcaciaSlab; + mappings[117] = ItemType.DarkOakSlab; + mappings[118] = ItemType.StoneSlab; + mappings[119] = ItemType.SandstoneSlab; + mappings[120] = ItemType.PetrifiedOakSlab; + mappings[121] = ItemType.CobblestoneSlab; + mappings[122] = ItemType.BrickSlab; + mappings[123] = ItemType.StoneBrickSlab; + mappings[124] = ItemType.NetherBrickSlab; + mappings[125] = ItemType.QuartzSlab; + mappings[126] = ItemType.RedSandstoneSlab; + mappings[127] = ItemType.PurpurSlab; + mappings[128] = ItemType.PrismarineSlab; + mappings[129] = ItemType.PrismarineBrickSlab; + mappings[130] = ItemType.DarkPrismarineSlab; + mappings[131] = ItemType.SmoothQuartz; + mappings[132] = ItemType.SmoothRedSandstone; + mappings[133] = ItemType.SmoothSandstone; + mappings[134] = ItemType.SmoothStone; + mappings[135] = ItemType.Bricks; + mappings[136] = ItemType.Tnt; + mappings[137] = ItemType.Bookshelf; + mappings[138] = ItemType.MossyCobblestone; + mappings[139] = ItemType.Obsidian; + mappings[140] = ItemType.Torch; + mappings[141] = ItemType.EndRod; + mappings[142] = ItemType.ChorusPlant; + mappings[143] = ItemType.ChorusFlower; + mappings[144] = ItemType.PurpurBlock; + mappings[145] = ItemType.PurpurPillar; + mappings[146] = ItemType.PurpurStairs; + mappings[147] = ItemType.Spawner; + mappings[148] = ItemType.OakStairs; + mappings[149] = ItemType.Chest; + mappings[150] = ItemType.DiamondOre; + mappings[151] = ItemType.DiamondBlock; + mappings[152] = ItemType.CraftingTable; + mappings[153] = ItemType.Farmland; + mappings[154] = ItemType.Furnace; + mappings[155] = ItemType.Ladder; + mappings[156] = ItemType.Rail; + mappings[157] = ItemType.CobblestoneStairs; + mappings[158] = ItemType.Lever; + mappings[159] = ItemType.StonePressurePlate; + mappings[160] = ItemType.OakPressurePlate; + mappings[161] = ItemType.SprucePressurePlate; + mappings[162] = ItemType.BirchPressurePlate; + mappings[163] = ItemType.JunglePressurePlate; + mappings[164] = ItemType.AcaciaPressurePlate; + mappings[165] = ItemType.DarkOakPressurePlate; + mappings[166] = ItemType.RedstoneOre; + mappings[167] = ItemType.RedstoneTorch; + mappings[168] = ItemType.StoneButton; + mappings[169] = ItemType.Snow; + mappings[170] = ItemType.Ice; + mappings[171] = ItemType.SnowBlock; + mappings[172] = ItemType.Cactus; + mappings[173] = ItemType.Clay; + mappings[174] = ItemType.Jukebox; + mappings[175] = ItemType.OakFence; + mappings[176] = ItemType.SpruceFence; + mappings[177] = ItemType.BirchFence; + mappings[178] = ItemType.JungleFence; + mappings[179] = ItemType.AcaciaFence; + mappings[180] = ItemType.DarkOakFence; + mappings[181] = ItemType.Pumpkin; + mappings[182] = ItemType.CarvedPumpkin; + mappings[183] = ItemType.Netherrack; + mappings[184] = ItemType.SoulSand; + mappings[185] = ItemType.Glowstone; + mappings[186] = ItemType.JackOLantern; + mappings[187] = ItemType.OakTrapdoor; + mappings[188] = ItemType.SpruceTrapdoor; + mappings[189] = ItemType.BirchTrapdoor; + mappings[190] = ItemType.JungleTrapdoor; + mappings[191] = ItemType.AcaciaTrapdoor; + mappings[192] = ItemType.DarkOakTrapdoor; + mappings[193] = ItemType.InfestedStone; + mappings[194] = ItemType.InfestedCobblestone; + mappings[195] = ItemType.InfestedStoneBricks; + mappings[196] = ItemType.InfestedMossyStoneBricks; + mappings[197] = ItemType.InfestedCrackedStoneBricks; + mappings[198] = ItemType.InfestedChiseledStoneBricks; + mappings[199] = ItemType.StoneBricks; + mappings[200] = ItemType.MossyStoneBricks; + mappings[201] = ItemType.CrackedStoneBricks; + mappings[202] = ItemType.ChiseledStoneBricks; + mappings[203] = ItemType.BrownMushroomBlock; + mappings[204] = ItemType.RedMushroomBlock; + mappings[205] = ItemType.MushroomStem; + mappings[206] = ItemType.IronBars; + mappings[207] = ItemType.GlassPane; + mappings[208] = ItemType.Melon; + mappings[209] = ItemType.Vine; + mappings[210] = ItemType.OakFenceGate; + mappings[211] = ItemType.SpruceFenceGate; + mappings[212] = ItemType.BirchFenceGate; + mappings[213] = ItemType.JungleFenceGate; + mappings[214] = ItemType.AcaciaFenceGate; + mappings[215] = ItemType.DarkOakFenceGate; + mappings[216] = ItemType.BrickStairs; + mappings[217] = ItemType.StoneBrickStairs; + mappings[218] = ItemType.Mycelium; + mappings[219] = ItemType.LilyPad; + mappings[220] = ItemType.NetherBricks; + mappings[221] = ItemType.NetherBrickFence; + mappings[222] = ItemType.NetherBrickStairs; + mappings[223] = ItemType.EnchantingTable; + mappings[224] = ItemType.EndPortalFrame; + mappings[225] = ItemType.EndStone; + mappings[226] = ItemType.EndStoneBricks; + mappings[227] = ItemType.DragonEgg; + mappings[228] = ItemType.RedstoneLamp; + mappings[229] = ItemType.SandstoneStairs; + mappings[230] = ItemType.EmeraldOre; + mappings[231] = ItemType.EnderChest; + mappings[232] = ItemType.TripwireHook; + mappings[233] = ItemType.EmeraldBlock; + mappings[234] = ItemType.SpruceStairs; + mappings[235] = ItemType.BirchStairs; + mappings[236] = ItemType.JungleStairs; + mappings[237] = ItemType.CommandBlock; + mappings[238] = ItemType.Beacon; + mappings[239] = ItemType.CobblestoneWall; + mappings[240] = ItemType.MossyCobblestoneWall; + mappings[241] = ItemType.OakButton; + mappings[242] = ItemType.SpruceButton; + mappings[243] = ItemType.BirchButton; + mappings[244] = ItemType.JungleButton; + mappings[245] = ItemType.AcaciaButton; + mappings[246] = ItemType.DarkOakButton; + mappings[247] = ItemType.Anvil; + mappings[248] = ItemType.ChippedAnvil; + mappings[249] = ItemType.DamagedAnvil; + mappings[250] = ItemType.TrappedChest; + mappings[251] = ItemType.LightWeightedPressurePlate; + mappings[252] = ItemType.HeavyWeightedPressurePlate; + mappings[253] = ItemType.DaylightDetector; + mappings[254] = ItemType.RedstoneBlock; + mappings[255] = ItemType.NetherQuartzOre; + mappings[256] = ItemType.Hopper; + mappings[257] = ItemType.ChiseledQuartzBlock; + mappings[258] = ItemType.QuartzBlock; + mappings[259] = ItemType.QuartzPillar; + mappings[260] = ItemType.QuartzStairs; + mappings[261] = ItemType.ActivatorRail; + mappings[262] = ItemType.Dropper; + mappings[263] = ItemType.WhiteTerracotta; + mappings[264] = ItemType.OrangeTerracotta; + mappings[265] = ItemType.MagentaTerracotta; + mappings[266] = ItemType.LightBlueTerracotta; + mappings[267] = ItemType.YellowTerracotta; + mappings[268] = ItemType.LimeTerracotta; + mappings[269] = ItemType.PinkTerracotta; + mappings[270] = ItemType.GrayTerracotta; + mappings[271] = ItemType.LightGrayTerracotta; + mappings[272] = ItemType.CyanTerracotta; + mappings[273] = ItemType.PurpleTerracotta; + mappings[274] = ItemType.BlueTerracotta; + mappings[275] = ItemType.BrownTerracotta; + mappings[276] = ItemType.GreenTerracotta; + mappings[277] = ItemType.RedTerracotta; + mappings[278] = ItemType.BlackTerracotta; + mappings[279] = ItemType.Barrier; + mappings[280] = ItemType.IronTrapdoor; + mappings[281] = ItemType.HayBlock; + mappings[282] = ItemType.WhiteCarpet; + mappings[283] = ItemType.OrangeCarpet; + mappings[284] = ItemType.MagentaCarpet; + mappings[285] = ItemType.LightBlueCarpet; + mappings[286] = ItemType.YellowCarpet; + mappings[287] = ItemType.LimeCarpet; + mappings[288] = ItemType.PinkCarpet; + mappings[289] = ItemType.GrayCarpet; + mappings[290] = ItemType.LightGrayCarpet; + mappings[291] = ItemType.CyanCarpet; + mappings[292] = ItemType.PurpleCarpet; + mappings[293] = ItemType.BlueCarpet; + mappings[294] = ItemType.BrownCarpet; + mappings[295] = ItemType.GreenCarpet; + mappings[296] = ItemType.RedCarpet; + mappings[297] = ItemType.BlackCarpet; + mappings[298] = ItemType.Terracotta; + mappings[299] = ItemType.CoalBlock; + mappings[300] = ItemType.PackedIce; + mappings[301] = ItemType.AcaciaStairs; + mappings[302] = ItemType.DarkOakStairs; + mappings[303] = ItemType.SlimeBlock; + mappings[304] = ItemType.DirtPath; + mappings[305] = ItemType.Sunflower; + mappings[306] = ItemType.Lilac; + mappings[307] = ItemType.RoseBush; + mappings[308] = ItemType.Peony; + mappings[309] = ItemType.TallGrass; + mappings[310] = ItemType.LargeFern; + mappings[311] = ItemType.WhiteStainedGlass; + mappings[312] = ItemType.OrangeStainedGlass; + mappings[313] = ItemType.MagentaStainedGlass; + mappings[314] = ItemType.LightBlueStainedGlass; + mappings[315] = ItemType.YellowStainedGlass; + mappings[316] = ItemType.LimeStainedGlass; + mappings[317] = ItemType.PinkStainedGlass; + mappings[318] = ItemType.GrayStainedGlass; + mappings[319] = ItemType.LightGrayStainedGlass; + mappings[320] = ItemType.CyanStainedGlass; + mappings[321] = ItemType.PurpleStainedGlass; + mappings[322] = ItemType.BlueStainedGlass; + mappings[323] = ItemType.BrownStainedGlass; + mappings[324] = ItemType.GreenStainedGlass; + mappings[325] = ItemType.RedStainedGlass; + mappings[326] = ItemType.BlackStainedGlass; + mappings[327] = ItemType.WhiteStainedGlassPane; + mappings[328] = ItemType.OrangeStainedGlassPane; + mappings[329] = ItemType.MagentaStainedGlassPane; + mappings[330] = ItemType.LightBlueStainedGlassPane; + mappings[331] = ItemType.YellowStainedGlassPane; + mappings[332] = ItemType.LimeStainedGlassPane; + mappings[333] = ItemType.PinkStainedGlassPane; + mappings[334] = ItemType.GrayStainedGlassPane; + mappings[335] = ItemType.LightGrayStainedGlassPane; + mappings[336] = ItemType.CyanStainedGlassPane; + mappings[337] = ItemType.PurpleStainedGlassPane; + mappings[338] = ItemType.BlueStainedGlassPane; + mappings[339] = ItemType.BrownStainedGlassPane; + mappings[340] = ItemType.GreenStainedGlassPane; + mappings[341] = ItemType.RedStainedGlassPane; + mappings[342] = ItemType.BlackStainedGlassPane; + mappings[343] = ItemType.Prismarine; + mappings[344] = ItemType.PrismarineBricks; + mappings[345] = ItemType.DarkPrismarine; + mappings[346] = ItemType.PrismarineStairs; + mappings[347] = ItemType.PrismarineBrickStairs; + mappings[348] = ItemType.DarkPrismarineStairs; + mappings[349] = ItemType.SeaLantern; + mappings[350] = ItemType.RedSandstone; + mappings[351] = ItemType.ChiseledRedSandstone; + mappings[352] = ItemType.CutRedSandstone; + mappings[353] = ItemType.RedSandstoneStairs; + mappings[354] = ItemType.RepeatingCommandBlock; + mappings[355] = ItemType.ChainCommandBlock; + mappings[356] = ItemType.MagmaBlock; + mappings[357] = ItemType.NetherWartBlock; + mappings[358] = ItemType.RedNetherBricks; + mappings[359] = ItemType.BoneBlock; + mappings[360] = ItemType.StructureVoid; + mappings[361] = ItemType.Observer; + mappings[362] = ItemType.ShulkerBox; + mappings[363] = ItemType.WhiteShulkerBox; + mappings[364] = ItemType.OrangeShulkerBox; + mappings[365] = ItemType.MagentaShulkerBox; + mappings[366] = ItemType.LightBlueShulkerBox; + mappings[367] = ItemType.YellowShulkerBox; + mappings[368] = ItemType.LimeShulkerBox; + mappings[369] = ItemType.PinkShulkerBox; + mappings[370] = ItemType.GrayShulkerBox; + mappings[371] = ItemType.LightGrayShulkerBox; + mappings[372] = ItemType.CyanShulkerBox; + mappings[373] = ItemType.PurpleShulkerBox; + mappings[374] = ItemType.BlueShulkerBox; + mappings[375] = ItemType.BrownShulkerBox; + mappings[376] = ItemType.GreenShulkerBox; + mappings[377] = ItemType.RedShulkerBox; + mappings[378] = ItemType.BlackShulkerBox; + mappings[379] = ItemType.WhiteGlazedTerracotta; + mappings[380] = ItemType.OrangeGlazedTerracotta; + mappings[381] = ItemType.MagentaGlazedTerracotta; + mappings[382] = ItemType.LightBlueGlazedTerracotta; + mappings[383] = ItemType.YellowGlazedTerracotta; + mappings[384] = ItemType.LimeGlazedTerracotta; + mappings[385] = ItemType.PinkGlazedTerracotta; + mappings[386] = ItemType.GrayGlazedTerracotta; + mappings[387] = ItemType.LightGrayGlazedTerracotta; + mappings[388] = ItemType.CyanGlazedTerracotta; + mappings[389] = ItemType.PurpleGlazedTerracotta; + mappings[390] = ItemType.BlueGlazedTerracotta; + mappings[391] = ItemType.BrownGlazedTerracotta; + mappings[392] = ItemType.GreenGlazedTerracotta; + mappings[393] = ItemType.RedGlazedTerracotta; + mappings[394] = ItemType.BlackGlazedTerracotta; + mappings[395] = ItemType.WhiteConcrete; + mappings[396] = ItemType.OrangeConcrete; + mappings[397] = ItemType.MagentaConcrete; + mappings[398] = ItemType.LightBlueConcrete; + mappings[399] = ItemType.YellowConcrete; + mappings[400] = ItemType.LimeConcrete; + mappings[401] = ItemType.PinkConcrete; + mappings[402] = ItemType.GrayConcrete; + mappings[403] = ItemType.LightGrayConcrete; + mappings[404] = ItemType.CyanConcrete; + mappings[405] = ItemType.PurpleConcrete; + mappings[406] = ItemType.BlueConcrete; + mappings[407] = ItemType.BrownConcrete; + mappings[408] = ItemType.GreenConcrete; + mappings[409] = ItemType.RedConcrete; + mappings[410] = ItemType.BlackConcrete; + mappings[411] = ItemType.WhiteConcretePowder; + mappings[412] = ItemType.OrangeConcretePowder; + mappings[413] = ItemType.MagentaConcretePowder; + mappings[414] = ItemType.LightBlueConcretePowder; + mappings[415] = ItemType.YellowConcretePowder; + mappings[416] = ItemType.LimeConcretePowder; + mappings[417] = ItemType.PinkConcretePowder; + mappings[418] = ItemType.GrayConcretePowder; + mappings[419] = ItemType.LightGrayConcretePowder; + mappings[420] = ItemType.CyanConcretePowder; + mappings[421] = ItemType.PurpleConcretePowder; + mappings[422] = ItemType.BlueConcretePowder; + mappings[423] = ItemType.BrownConcretePowder; + mappings[424] = ItemType.GreenConcretePowder; + mappings[425] = ItemType.RedConcretePowder; + mappings[426] = ItemType.BlackConcretePowder; + mappings[427] = ItemType.TurtleEgg; + mappings[428] = ItemType.DeadTubeCoralBlock; + mappings[429] = ItemType.DeadBrainCoralBlock; + mappings[430] = ItemType.DeadBubbleCoralBlock; + mappings[431] = ItemType.DeadFireCoralBlock; + mappings[432] = ItemType.DeadHornCoralBlock; + mappings[433] = ItemType.TubeCoralBlock; + mappings[434] = ItemType.BrainCoralBlock; + mappings[435] = ItemType.BubbleCoralBlock; + mappings[436] = ItemType.FireCoralBlock; + mappings[437] = ItemType.HornCoralBlock; + mappings[438] = ItemType.TubeCoral; + mappings[439] = ItemType.BrainCoral; + mappings[440] = ItemType.BubbleCoral; + mappings[441] = ItemType.FireCoral; + mappings[442] = ItemType.HornCoral; + mappings[443] = ItemType.TubeCoralFan; + mappings[444] = ItemType.BrainCoralFan; + mappings[445] = ItemType.BubbleCoralFan; + mappings[446] = ItemType.FireCoralFan; + mappings[447] = ItemType.HornCoralFan; + mappings[448] = ItemType.DeadTubeCoralFan; + mappings[449] = ItemType.DeadBrainCoralFan; + mappings[450] = ItemType.DeadBubbleCoralFan; + mappings[451] = ItemType.DeadFireCoralFan; + mappings[452] = ItemType.DeadHornCoralFan; + mappings[453] = ItemType.BlueIce; + mappings[454] = ItemType.Conduit; + mappings[455] = ItemType.IronDoor; + mappings[456] = ItemType.OakDoor; + mappings[457] = ItemType.SpruceDoor; + mappings[458] = ItemType.BirchDoor; + mappings[459] = ItemType.JungleDoor; + mappings[460] = ItemType.AcaciaDoor; + mappings[461] = ItemType.DarkOakDoor; + mappings[462] = ItemType.Repeater; + mappings[463] = ItemType.Comparator; + mappings[464] = ItemType.StructureBlock; + mappings[465] = ItemType.TurtleHelmet; + mappings[466] = ItemType.TurtleScute; + mappings[467] = ItemType.IronShovel; + mappings[468] = ItemType.IronPickaxe; + mappings[469] = ItemType.IronAxe; + mappings[470] = ItemType.FlintAndSteel; + mappings[471] = ItemType.Apple; + mappings[472] = ItemType.Bow; + mappings[473] = ItemType.Arrow; + mappings[474] = ItemType.Coal; + mappings[475] = ItemType.Charcoal; + mappings[476] = ItemType.Diamond; + mappings[477] = ItemType.IronIngot; + mappings[478] = ItemType.GoldIngot; + mappings[479] = ItemType.IronSword; + mappings[480] = ItemType.WoodenSword; + mappings[481] = ItemType.WoodenShovel; + mappings[482] = ItemType.WoodenPickaxe; + mappings[483] = ItemType.WoodenAxe; + mappings[484] = ItemType.StoneSword; + mappings[485] = ItemType.StoneShovel; + mappings[486] = ItemType.StonePickaxe; + mappings[487] = ItemType.StoneAxe; + mappings[488] = ItemType.DiamondSword; + mappings[489] = ItemType.DiamondShovel; + mappings[490] = ItemType.DiamondPickaxe; + mappings[491] = ItemType.DiamondAxe; + mappings[492] = ItemType.Stick; + mappings[493] = ItemType.Bowl; + mappings[494] = ItemType.MushroomStew; + mappings[495] = ItemType.GoldenSword; + mappings[496] = ItemType.GoldenShovel; + mappings[497] = ItemType.GoldenPickaxe; + mappings[498] = ItemType.GoldenAxe; + mappings[499] = ItemType.String; + mappings[500] = ItemType.Feather; + mappings[501] = ItemType.Gunpowder; + mappings[502] = ItemType.WoodenHoe; + mappings[503] = ItemType.StoneHoe; + mappings[504] = ItemType.IronHoe; + mappings[505] = ItemType.DiamondHoe; + mappings[506] = ItemType.GoldenHoe; + mappings[507] = ItemType.WheatSeeds; + mappings[508] = ItemType.Wheat; + mappings[509] = ItemType.Bread; + mappings[510] = ItemType.LeatherHelmet; + mappings[511] = ItemType.LeatherChestplate; + mappings[512] = ItemType.LeatherLeggings; + mappings[513] = ItemType.LeatherBoots; + mappings[514] = ItemType.ChainmailHelmet; + mappings[515] = ItemType.ChainmailChestplate; + mappings[516] = ItemType.ChainmailLeggings; + mappings[517] = ItemType.ChainmailBoots; + mappings[518] = ItemType.IronHelmet; + mappings[519] = ItemType.IronChestplate; + mappings[520] = ItemType.IronLeggings; + mappings[521] = ItemType.IronBoots; + mappings[522] = ItemType.DiamondHelmet; + mappings[523] = ItemType.DiamondChestplate; + mappings[524] = ItemType.DiamondLeggings; + mappings[525] = ItemType.DiamondBoots; + mappings[526] = ItemType.GoldenHelmet; + mappings[527] = ItemType.GoldenChestplate; + mappings[528] = ItemType.GoldenLeggings; + mappings[529] = ItemType.GoldenBoots; + mappings[530] = ItemType.Flint; + mappings[531] = ItemType.Porkchop; + mappings[532] = ItemType.CookedPorkchop; + mappings[533] = ItemType.Painting; + mappings[534] = ItemType.GoldenApple; + mappings[535] = ItemType.EnchantedGoldenApple; + mappings[536] = ItemType.OakSign; + mappings[537] = ItemType.Bucket; + mappings[538] = ItemType.WaterBucket; + mappings[539] = ItemType.LavaBucket; + mappings[540] = ItemType.Minecart; + mappings[541] = ItemType.Saddle; + mappings[542] = ItemType.Redstone; + mappings[543] = ItemType.Snowball; + mappings[544] = ItemType.OakBoat; + mappings[545] = ItemType.Leather; + mappings[546] = ItemType.MilkBucket; + mappings[547] = ItemType.PufferfishBucket; + mappings[548] = ItemType.SalmonBucket; + mappings[549] = ItemType.CodBucket; + mappings[550] = ItemType.TropicalFishBucket; + mappings[551] = ItemType.Brick; + mappings[552] = ItemType.ClayBall; + mappings[553] = ItemType.SugarCane; + mappings[554] = ItemType.Kelp; + mappings[555] = ItemType.DriedKelpBlock; + mappings[556] = ItemType.Paper; + mappings[557] = ItemType.Book; + mappings[558] = ItemType.SlimeBall; + mappings[559] = ItemType.ChestMinecart; + mappings[560] = ItemType.FurnaceMinecart; + mappings[561] = ItemType.Egg; + mappings[562] = ItemType.Compass; + mappings[563] = ItemType.FishingRod; + mappings[564] = ItemType.Clock; + mappings[565] = ItemType.GlowstoneDust; + mappings[566] = ItemType.Cod; + mappings[567] = ItemType.Salmon; + mappings[568] = ItemType.TropicalFish; + mappings[569] = ItemType.Pufferfish; + mappings[570] = ItemType.CookedCod; + mappings[571] = ItemType.CookedSalmon; + mappings[572] = ItemType.InkSac; + mappings[573] = ItemType.RedDye; + mappings[574] = ItemType.GreenDye; + mappings[575] = ItemType.CocoaBeans; + mappings[576] = ItemType.LapisLazuli; + mappings[577] = ItemType.PurpleDye; + mappings[578] = ItemType.CyanDye; + mappings[579] = ItemType.LightGrayDye; + mappings[580] = ItemType.GrayDye; + mappings[581] = ItemType.PinkDye; + mappings[582] = ItemType.LimeDye; + mappings[583] = ItemType.YellowDye; + mappings[584] = ItemType.LightBlueDye; + mappings[585] = ItemType.MagentaDye; + mappings[586] = ItemType.OrangeDye; + mappings[587] = ItemType.BoneMeal; + mappings[588] = ItemType.Bone; + mappings[589] = ItemType.Sugar; + mappings[590] = ItemType.Cake; + mappings[591] = ItemType.WhiteBed; + mappings[592] = ItemType.OrangeBed; + mappings[593] = ItemType.MagentaBed; + mappings[594] = ItemType.LightBlueBed; + mappings[595] = ItemType.YellowBed; + mappings[596] = ItemType.LimeBed; + mappings[597] = ItemType.PinkBed; + mappings[598] = ItemType.GrayBed; + mappings[599] = ItemType.LightGrayBed; + mappings[600] = ItemType.CyanBed; + mappings[601] = ItemType.PurpleBed; + mappings[602] = ItemType.BlueBed; + mappings[603] = ItemType.BrownBed; + mappings[604] = ItemType.GreenBed; + mappings[605] = ItemType.RedBed; + mappings[606] = ItemType.BlackBed; + mappings[607] = ItemType.Cookie; + mappings[608] = ItemType.FilledMap; + mappings[609] = ItemType.Shears; + mappings[610] = ItemType.MelonSlice; + mappings[611] = ItemType.DriedKelp; + mappings[612] = ItemType.PumpkinSeeds; + mappings[613] = ItemType.MelonSeeds; + mappings[614] = ItemType.Beef; + mappings[615] = ItemType.CookedBeef; + mappings[616] = ItemType.Chicken; + mappings[617] = ItemType.CookedChicken; + mappings[618] = ItemType.RottenFlesh; + mappings[619] = ItemType.EnderPearl; + mappings[620] = ItemType.BlazeRod; + mappings[621] = ItemType.GhastTear; + mappings[622] = ItemType.GoldNugget; + mappings[623] = ItemType.NetherWart; + mappings[624] = ItemType.Potion; + mappings[625] = ItemType.GlassBottle; + mappings[626] = ItemType.SpiderEye; + mappings[627] = ItemType.FermentedSpiderEye; + mappings[628] = ItemType.BlazePowder; + mappings[629] = ItemType.MagmaCream; + mappings[630] = ItemType.BrewingStand; + mappings[631] = ItemType.Cauldron; + mappings[632] = ItemType.EnderEye; + mappings[633] = ItemType.GlisteringMelonSlice; + mappings[634] = ItemType.BatSpawnEgg; + mappings[635] = ItemType.BlazeSpawnEgg; + mappings[636] = ItemType.CaveSpiderSpawnEgg; + mappings[637] = ItemType.ChickenSpawnEgg; + mappings[638] = ItemType.CodSpawnEgg; + mappings[639] = ItemType.CowSpawnEgg; + mappings[640] = ItemType.CreeperSpawnEgg; + mappings[641] = ItemType.DolphinSpawnEgg; + mappings[642] = ItemType.DonkeySpawnEgg; + mappings[643] = ItemType.DrownedSpawnEgg; + mappings[644] = ItemType.ElderGuardianSpawnEgg; + mappings[645] = ItemType.EndermanSpawnEgg; + mappings[646] = ItemType.EndermiteSpawnEgg; + mappings[647] = ItemType.EvokerSpawnEgg; + mappings[648] = ItemType.GhastSpawnEgg; + mappings[649] = ItemType.GuardianSpawnEgg; + mappings[650] = ItemType.HorseSpawnEgg; + mappings[651] = ItemType.HuskSpawnEgg; + mappings[652] = ItemType.LlamaSpawnEgg; + mappings[653] = ItemType.MagmaCubeSpawnEgg; + mappings[654] = ItemType.MooshroomSpawnEgg; + mappings[655] = ItemType.MuleSpawnEgg; + mappings[656] = ItemType.OcelotSpawnEgg; + mappings[657] = ItemType.ParrotSpawnEgg; + mappings[658] = ItemType.PhantomSpawnEgg; + mappings[659] = ItemType.PigSpawnEgg; + mappings[660] = ItemType.PolarBearSpawnEgg; + mappings[661] = ItemType.PufferfishSpawnEgg; + mappings[662] = ItemType.RabbitSpawnEgg; + mappings[663] = ItemType.SalmonSpawnEgg; + mappings[664] = ItemType.SheepSpawnEgg; + mappings[665] = ItemType.ShulkerSpawnEgg; + mappings[666] = ItemType.SilverfishSpawnEgg; + mappings[667] = ItemType.SkeletonSpawnEgg; + mappings[668] = ItemType.SkeletonHorseSpawnEgg; + mappings[669] = ItemType.SlimeSpawnEgg; + mappings[670] = ItemType.SpiderSpawnEgg; + mappings[671] = ItemType.SquidSpawnEgg; + mappings[672] = ItemType.StraySpawnEgg; + mappings[673] = ItemType.TropicalFishSpawnEgg; + mappings[674] = ItemType.TurtleSpawnEgg; + mappings[675] = ItemType.VexSpawnEgg; + mappings[676] = ItemType.VillagerSpawnEgg; + mappings[677] = ItemType.VindicatorSpawnEgg; + mappings[678] = ItemType.WitchSpawnEgg; + mappings[679] = ItemType.WitherSkeletonSpawnEgg; + mappings[680] = ItemType.WolfSpawnEgg; + mappings[681] = ItemType.ZombieSpawnEgg; + mappings[682] = ItemType.ZombieHorseSpawnEgg; + mappings[683] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[684] = ItemType.ZombieVillagerSpawnEgg; + mappings[685] = ItemType.ExperienceBottle; + mappings[686] = ItemType.FireCharge; + mappings[687] = ItemType.WritableBook; + mappings[688] = ItemType.WrittenBook; + mappings[689] = ItemType.Emerald; + mappings[690] = ItemType.ItemFrame; + mappings[691] = ItemType.FlowerPot; + mappings[692] = ItemType.Carrot; + mappings[693] = ItemType.Potato; + mappings[694] = ItemType.BakedPotato; + mappings[695] = ItemType.PoisonousPotato; + mappings[696] = ItemType.Map; + mappings[697] = ItemType.GoldenCarrot; + mappings[698] = ItemType.SkeletonSkull; + mappings[699] = ItemType.WitherSkeletonSkull; + mappings[700] = ItemType.PlayerHead; + mappings[701] = ItemType.ZombieHead; + mappings[702] = ItemType.CreeperHead; + mappings[703] = ItemType.DragonHead; + mappings[704] = ItemType.CarrotOnAStick; + mappings[705] = ItemType.NetherStar; + mappings[706] = ItemType.PumpkinPie; + mappings[707] = ItemType.FireworkRocket; + mappings[708] = ItemType.FireworkStar; + mappings[709] = ItemType.EnchantedBook; + mappings[710] = ItemType.NetherBrick; + mappings[711] = ItemType.Quartz; + mappings[712] = ItemType.TntMinecart; + mappings[713] = ItemType.HopperMinecart; + mappings[714] = ItemType.PrismarineShard; + mappings[715] = ItemType.PrismarineCrystals; + mappings[716] = ItemType.Rabbit; + mappings[717] = ItemType.CookedRabbit; + mappings[718] = ItemType.RabbitStew; + mappings[719] = ItemType.RabbitFoot; + mappings[720] = ItemType.RabbitHide; + mappings[721] = ItemType.ArmorStand; + mappings[722] = ItemType.IronHorseArmor; + mappings[723] = ItemType.GoldenHorseArmor; + mappings[724] = ItemType.DiamondHorseArmor; + mappings[725] = ItemType.Lead; + mappings[726] = ItemType.NameTag; + mappings[727] = ItemType.CommandBlockMinecart; + mappings[728] = ItemType.Mutton; + mappings[729] = ItemType.CookedMutton; + mappings[730] = ItemType.WhiteBanner; + mappings[731] = ItemType.OrangeBanner; + mappings[732] = ItemType.MagentaBanner; + mappings[733] = ItemType.LightBlueBanner; + mappings[734] = ItemType.YellowBanner; + mappings[735] = ItemType.LimeBanner; + mappings[736] = ItemType.PinkBanner; + mappings[737] = ItemType.GrayBanner; + mappings[738] = ItemType.LightGrayBanner; + mappings[739] = ItemType.CyanBanner; + mappings[740] = ItemType.PurpleBanner; + mappings[741] = ItemType.BlueBanner; + mappings[742] = ItemType.BrownBanner; + mappings[743] = ItemType.GreenBanner; + mappings[744] = ItemType.RedBanner; + mappings[745] = ItemType.BlackBanner; + mappings[746] = ItemType.EndCrystal; + mappings[747] = ItemType.ChorusFruit; + mappings[748] = ItemType.PoppedChorusFruit; + mappings[749] = ItemType.Beetroot; + mappings[750] = ItemType.BeetrootSeeds; + mappings[751] = ItemType.BeetrootSoup; + mappings[752] = ItemType.DragonBreath; + mappings[753] = ItemType.SplashPotion; + mappings[754] = ItemType.SpectralArrow; + mappings[755] = ItemType.TippedArrow; + mappings[756] = ItemType.LingeringPotion; + mappings[757] = ItemType.Shield; + mappings[758] = ItemType.Elytra; + mappings[759] = ItemType.SpruceBoat; + mappings[760] = ItemType.BirchBoat; + mappings[761] = ItemType.JungleBoat; + mappings[762] = ItemType.AcaciaBoat; + mappings[763] = ItemType.DarkOakBoat; + mappings[764] = ItemType.TotemOfUndying; + mappings[765] = ItemType.ShulkerShell; + mappings[766] = ItemType.IronNugget; + mappings[767] = ItemType.KnowledgeBook; + mappings[768] = ItemType.DebugStick; + mappings[769] = ItemType.MusicDisc13; + mappings[770] = ItemType.MusicDiscCat; + mappings[771] = ItemType.MusicDiscBlocks; + mappings[772] = ItemType.MusicDiscChirp; + mappings[773] = ItemType.MusicDiscFar; + mappings[774] = ItemType.MusicDiscMall; + mappings[775] = ItemType.MusicDiscMellohi; + mappings[776] = ItemType.MusicDiscStal; + mappings[777] = ItemType.MusicDiscStrad; + mappings[778] = ItemType.MusicDiscWard; + mappings[779] = ItemType.MusicDisc11; + mappings[780] = ItemType.MusicDiscWait; + mappings[781] = ItemType.Trident; + mappings[782] = ItemType.PhantomMembrane; + mappings[783] = ItemType.NautilusShell; + mappings[784] = ItemType.HeartOfTheSea; + } protected override Dictionary<int, ItemType> GetDict() { diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs index 24da1d8f..da38b041 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1132.cs @@ -2,17 +2,803 @@ using System.Collections.Generic; namespace MinecraftClient.Inventory.ItemPalettes { - /// <summary> - /// Minimal flattened item palette for 1.13.2 book handling. - /// </summary> public class ItemPalette1132 : ItemPalette { - private static readonly Dictionary<int, ItemType> mappings = new() + private static readonly Dictionary<int, ItemType> mappings = new(); + + static ItemPalette1132() { - [0] = ItemType.Air, - [692] = ItemType.WritableBook, - [693] = ItemType.WrittenBook - }; + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.GrassBlock; + mappings[9] = ItemType.Dirt; + mappings[10] = ItemType.CoarseDirt; + mappings[11] = ItemType.Podzol; + mappings[12] = ItemType.Cobblestone; + mappings[13] = ItemType.OakPlanks; + mappings[14] = ItemType.SprucePlanks; + mappings[15] = ItemType.BirchPlanks; + mappings[16] = ItemType.JunglePlanks; + mappings[17] = ItemType.AcaciaPlanks; + mappings[18] = ItemType.DarkOakPlanks; + mappings[19] = ItemType.OakSapling; + mappings[20] = ItemType.SpruceSapling; + mappings[21] = ItemType.BirchSapling; + mappings[22] = ItemType.JungleSapling; + mappings[23] = ItemType.AcaciaSapling; + mappings[24] = ItemType.DarkOakSapling; + mappings[25] = ItemType.Bedrock; + mappings[26] = ItemType.Sand; + mappings[27] = ItemType.RedSand; + mappings[28] = ItemType.Gravel; + mappings[29] = ItemType.GoldOre; + mappings[30] = ItemType.IronOre; + mappings[31] = ItemType.CoalOre; + mappings[32] = ItemType.OakLog; + mappings[33] = ItemType.SpruceLog; + mappings[34] = ItemType.BirchLog; + mappings[35] = ItemType.JungleLog; + mappings[36] = ItemType.AcaciaLog; + mappings[37] = ItemType.DarkOakLog; + mappings[38] = ItemType.StrippedOakLog; + mappings[39] = ItemType.StrippedSpruceLog; + mappings[40] = ItemType.StrippedBirchLog; + mappings[41] = ItemType.StrippedJungleLog; + mappings[42] = ItemType.StrippedAcaciaLog; + mappings[43] = ItemType.StrippedDarkOakLog; + mappings[44] = ItemType.StrippedOakWood; + mappings[45] = ItemType.StrippedSpruceWood; + mappings[46] = ItemType.StrippedBirchWood; + mappings[47] = ItemType.StrippedJungleWood; + mappings[48] = ItemType.StrippedAcaciaWood; + mappings[49] = ItemType.StrippedDarkOakWood; + mappings[50] = ItemType.OakWood; + mappings[51] = ItemType.SpruceWood; + mappings[52] = ItemType.BirchWood; + mappings[53] = ItemType.JungleWood; + mappings[54] = ItemType.AcaciaWood; + mappings[55] = ItemType.DarkOakWood; + mappings[56] = ItemType.OakLeaves; + mappings[57] = ItemType.SpruceLeaves; + mappings[58] = ItemType.BirchLeaves; + mappings[59] = ItemType.JungleLeaves; + mappings[60] = ItemType.AcaciaLeaves; + mappings[61] = ItemType.DarkOakLeaves; + mappings[62] = ItemType.Sponge; + mappings[63] = ItemType.WetSponge; + mappings[64] = ItemType.Glass; + mappings[65] = ItemType.LapisOre; + mappings[66] = ItemType.LapisBlock; + mappings[67] = ItemType.Dispenser; + mappings[68] = ItemType.Sandstone; + mappings[69] = ItemType.ChiseledSandstone; + mappings[70] = ItemType.CutSandstone; + mappings[71] = ItemType.NoteBlock; + mappings[72] = ItemType.PoweredRail; + mappings[73] = ItemType.DetectorRail; + mappings[74] = ItemType.StickyPiston; + mappings[75] = ItemType.Cobweb; + mappings[76] = ItemType.ShortGrass; + mappings[77] = ItemType.Fern; + mappings[78] = ItemType.DeadBush; + mappings[79] = ItemType.Seagrass; + mappings[80] = ItemType.SeaPickle; + mappings[81] = ItemType.Piston; + mappings[82] = ItemType.WhiteWool; + mappings[83] = ItemType.OrangeWool; + mappings[84] = ItemType.MagentaWool; + mappings[85] = ItemType.LightBlueWool; + mappings[86] = ItemType.YellowWool; + mappings[87] = ItemType.LimeWool; + mappings[88] = ItemType.PinkWool; + mappings[89] = ItemType.GrayWool; + mappings[90] = ItemType.LightGrayWool; + mappings[91] = ItemType.CyanWool; + mappings[92] = ItemType.PurpleWool; + mappings[93] = ItemType.BlueWool; + mappings[94] = ItemType.BrownWool; + mappings[95] = ItemType.GreenWool; + mappings[96] = ItemType.RedWool; + mappings[97] = ItemType.BlackWool; + mappings[98] = ItemType.Dandelion; + mappings[99] = ItemType.Poppy; + mappings[100] = ItemType.BlueOrchid; + mappings[101] = ItemType.Allium; + mappings[102] = ItemType.AzureBluet; + mappings[103] = ItemType.RedTulip; + mappings[104] = ItemType.OrangeTulip; + mappings[105] = ItemType.WhiteTulip; + mappings[106] = ItemType.PinkTulip; + mappings[107] = ItemType.OxeyeDaisy; + mappings[108] = ItemType.BrownMushroom; + mappings[109] = ItemType.RedMushroom; + mappings[110] = ItemType.GoldBlock; + mappings[111] = ItemType.IronBlock; + mappings[112] = ItemType.OakSlab; + mappings[113] = ItemType.SpruceSlab; + mappings[114] = ItemType.BirchSlab; + mappings[115] = ItemType.JungleSlab; + mappings[116] = ItemType.AcaciaSlab; + mappings[117] = ItemType.DarkOakSlab; + mappings[118] = ItemType.StoneSlab; + mappings[119] = ItemType.SandstoneSlab; + mappings[120] = ItemType.PetrifiedOakSlab; + mappings[121] = ItemType.CobblestoneSlab; + mappings[122] = ItemType.BrickSlab; + mappings[123] = ItemType.StoneBrickSlab; + mappings[124] = ItemType.NetherBrickSlab; + mappings[125] = ItemType.QuartzSlab; + mappings[126] = ItemType.RedSandstoneSlab; + mappings[127] = ItemType.PurpurSlab; + mappings[128] = ItemType.PrismarineSlab; + mappings[129] = ItemType.PrismarineBrickSlab; + mappings[130] = ItemType.DarkPrismarineSlab; + mappings[131] = ItemType.SmoothQuartz; + mappings[132] = ItemType.SmoothRedSandstone; + mappings[133] = ItemType.SmoothSandstone; + mappings[134] = ItemType.SmoothStone; + mappings[135] = ItemType.Bricks; + mappings[136] = ItemType.Tnt; + mappings[137] = ItemType.Bookshelf; + mappings[138] = ItemType.MossyCobblestone; + mappings[139] = ItemType.Obsidian; + mappings[140] = ItemType.Torch; + mappings[141] = ItemType.EndRod; + mappings[142] = ItemType.ChorusPlant; + mappings[143] = ItemType.ChorusFlower; + mappings[144] = ItemType.PurpurBlock; + mappings[145] = ItemType.PurpurPillar; + mappings[146] = ItemType.PurpurStairs; + mappings[147] = ItemType.Spawner; + mappings[148] = ItemType.OakStairs; + mappings[149] = ItemType.Chest; + mappings[150] = ItemType.DiamondOre; + mappings[151] = ItemType.DiamondBlock; + mappings[152] = ItemType.CraftingTable; + mappings[153] = ItemType.Farmland; + mappings[154] = ItemType.Furnace; + mappings[155] = ItemType.Ladder; + mappings[156] = ItemType.Rail; + mappings[157] = ItemType.CobblestoneStairs; + mappings[158] = ItemType.Lever; + mappings[159] = ItemType.StonePressurePlate; + mappings[160] = ItemType.OakPressurePlate; + mappings[161] = ItemType.SprucePressurePlate; + mappings[162] = ItemType.BirchPressurePlate; + mappings[163] = ItemType.JunglePressurePlate; + mappings[164] = ItemType.AcaciaPressurePlate; + mappings[165] = ItemType.DarkOakPressurePlate; + mappings[166] = ItemType.RedstoneOre; + mappings[167] = ItemType.RedstoneTorch; + mappings[168] = ItemType.StoneButton; + mappings[169] = ItemType.Snow; + mappings[170] = ItemType.Ice; + mappings[171] = ItemType.SnowBlock; + mappings[172] = ItemType.Cactus; + mappings[173] = ItemType.Clay; + mappings[174] = ItemType.Jukebox; + mappings[175] = ItemType.OakFence; + mappings[176] = ItemType.SpruceFence; + mappings[177] = ItemType.BirchFence; + mappings[178] = ItemType.JungleFence; + mappings[179] = ItemType.AcaciaFence; + mappings[180] = ItemType.DarkOakFence; + mappings[181] = ItemType.Pumpkin; + mappings[182] = ItemType.CarvedPumpkin; + mappings[183] = ItemType.Netherrack; + mappings[184] = ItemType.SoulSand; + mappings[185] = ItemType.Glowstone; + mappings[186] = ItemType.JackOLantern; + mappings[187] = ItemType.OakTrapdoor; + mappings[188] = ItemType.SpruceTrapdoor; + mappings[189] = ItemType.BirchTrapdoor; + mappings[190] = ItemType.JungleTrapdoor; + mappings[191] = ItemType.AcaciaTrapdoor; + mappings[192] = ItemType.DarkOakTrapdoor; + mappings[193] = ItemType.InfestedStone; + mappings[194] = ItemType.InfestedCobblestone; + mappings[195] = ItemType.InfestedStoneBricks; + mappings[196] = ItemType.InfestedMossyStoneBricks; + mappings[197] = ItemType.InfestedCrackedStoneBricks; + mappings[198] = ItemType.InfestedChiseledStoneBricks; + mappings[199] = ItemType.StoneBricks; + mappings[200] = ItemType.MossyStoneBricks; + mappings[201] = ItemType.CrackedStoneBricks; + mappings[202] = ItemType.ChiseledStoneBricks; + mappings[203] = ItemType.BrownMushroomBlock; + mappings[204] = ItemType.RedMushroomBlock; + mappings[205] = ItemType.MushroomStem; + mappings[206] = ItemType.IronBars; + mappings[207] = ItemType.GlassPane; + mappings[208] = ItemType.Melon; + mappings[209] = ItemType.Vine; + mappings[210] = ItemType.OakFenceGate; + mappings[211] = ItemType.SpruceFenceGate; + mappings[212] = ItemType.BirchFenceGate; + mappings[213] = ItemType.JungleFenceGate; + mappings[214] = ItemType.AcaciaFenceGate; + mappings[215] = ItemType.DarkOakFenceGate; + mappings[216] = ItemType.BrickStairs; + mappings[217] = ItemType.StoneBrickStairs; + mappings[218] = ItemType.Mycelium; + mappings[219] = ItemType.LilyPad; + mappings[220] = ItemType.NetherBricks; + mappings[221] = ItemType.NetherBrickFence; + mappings[222] = ItemType.NetherBrickStairs; + mappings[223] = ItemType.EnchantingTable; + mappings[224] = ItemType.EndPortalFrame; + mappings[225] = ItemType.EndStone; + mappings[226] = ItemType.EndStoneBricks; + mappings[227] = ItemType.DragonEgg; + mappings[228] = ItemType.RedstoneLamp; + mappings[229] = ItemType.SandstoneStairs; + mappings[230] = ItemType.EmeraldOre; + mappings[231] = ItemType.EnderChest; + mappings[232] = ItemType.TripwireHook; + mappings[233] = ItemType.EmeraldBlock; + mappings[234] = ItemType.SpruceStairs; + mappings[235] = ItemType.BirchStairs; + mappings[236] = ItemType.JungleStairs; + mappings[237] = ItemType.CommandBlock; + mappings[238] = ItemType.Beacon; + mappings[239] = ItemType.CobblestoneWall; + mappings[240] = ItemType.MossyCobblestoneWall; + mappings[241] = ItemType.OakButton; + mappings[242] = ItemType.SpruceButton; + mappings[243] = ItemType.BirchButton; + mappings[244] = ItemType.JungleButton; + mappings[245] = ItemType.AcaciaButton; + mappings[246] = ItemType.DarkOakButton; + mappings[247] = ItemType.Anvil; + mappings[248] = ItemType.ChippedAnvil; + mappings[249] = ItemType.DamagedAnvil; + mappings[250] = ItemType.TrappedChest; + mappings[251] = ItemType.LightWeightedPressurePlate; + mappings[252] = ItemType.HeavyWeightedPressurePlate; + mappings[253] = ItemType.DaylightDetector; + mappings[254] = ItemType.RedstoneBlock; + mappings[255] = ItemType.NetherQuartzOre; + mappings[256] = ItemType.Hopper; + mappings[257] = ItemType.ChiseledQuartzBlock; + mappings[258] = ItemType.QuartzBlock; + mappings[259] = ItemType.QuartzPillar; + mappings[260] = ItemType.QuartzStairs; + mappings[261] = ItemType.ActivatorRail; + mappings[262] = ItemType.Dropper; + mappings[263] = ItemType.WhiteTerracotta; + mappings[264] = ItemType.OrangeTerracotta; + mappings[265] = ItemType.MagentaTerracotta; + mappings[266] = ItemType.LightBlueTerracotta; + mappings[267] = ItemType.YellowTerracotta; + mappings[268] = ItemType.LimeTerracotta; + mappings[269] = ItemType.PinkTerracotta; + mappings[270] = ItemType.GrayTerracotta; + mappings[271] = ItemType.LightGrayTerracotta; + mappings[272] = ItemType.CyanTerracotta; + mappings[273] = ItemType.PurpleTerracotta; + mappings[274] = ItemType.BlueTerracotta; + mappings[275] = ItemType.BrownTerracotta; + mappings[276] = ItemType.GreenTerracotta; + mappings[277] = ItemType.RedTerracotta; + mappings[278] = ItemType.BlackTerracotta; + mappings[279] = ItemType.Barrier; + mappings[280] = ItemType.IronTrapdoor; + mappings[281] = ItemType.HayBlock; + mappings[282] = ItemType.WhiteCarpet; + mappings[283] = ItemType.OrangeCarpet; + mappings[284] = ItemType.MagentaCarpet; + mappings[285] = ItemType.LightBlueCarpet; + mappings[286] = ItemType.YellowCarpet; + mappings[287] = ItemType.LimeCarpet; + mappings[288] = ItemType.PinkCarpet; + mappings[289] = ItemType.GrayCarpet; + mappings[290] = ItemType.LightGrayCarpet; + mappings[291] = ItemType.CyanCarpet; + mappings[292] = ItemType.PurpleCarpet; + mappings[293] = ItemType.BlueCarpet; + mappings[294] = ItemType.BrownCarpet; + mappings[295] = ItemType.GreenCarpet; + mappings[296] = ItemType.RedCarpet; + mappings[297] = ItemType.BlackCarpet; + mappings[298] = ItemType.Terracotta; + mappings[299] = ItemType.CoalBlock; + mappings[300] = ItemType.PackedIce; + mappings[301] = ItemType.AcaciaStairs; + mappings[302] = ItemType.DarkOakStairs; + mappings[303] = ItemType.SlimeBlock; + mappings[304] = ItemType.DirtPath; + mappings[305] = ItemType.Sunflower; + mappings[306] = ItemType.Lilac; + mappings[307] = ItemType.RoseBush; + mappings[308] = ItemType.Peony; + mappings[309] = ItemType.TallGrass; + mappings[310] = ItemType.LargeFern; + mappings[311] = ItemType.WhiteStainedGlass; + mappings[312] = ItemType.OrangeStainedGlass; + mappings[313] = ItemType.MagentaStainedGlass; + mappings[314] = ItemType.LightBlueStainedGlass; + mappings[315] = ItemType.YellowStainedGlass; + mappings[316] = ItemType.LimeStainedGlass; + mappings[317] = ItemType.PinkStainedGlass; + mappings[318] = ItemType.GrayStainedGlass; + mappings[319] = ItemType.LightGrayStainedGlass; + mappings[320] = ItemType.CyanStainedGlass; + mappings[321] = ItemType.PurpleStainedGlass; + mappings[322] = ItemType.BlueStainedGlass; + mappings[323] = ItemType.BrownStainedGlass; + mappings[324] = ItemType.GreenStainedGlass; + mappings[325] = ItemType.RedStainedGlass; + mappings[326] = ItemType.BlackStainedGlass; + mappings[327] = ItemType.WhiteStainedGlassPane; + mappings[328] = ItemType.OrangeStainedGlassPane; + mappings[329] = ItemType.MagentaStainedGlassPane; + mappings[330] = ItemType.LightBlueStainedGlassPane; + mappings[331] = ItemType.YellowStainedGlassPane; + mappings[332] = ItemType.LimeStainedGlassPane; + mappings[333] = ItemType.PinkStainedGlassPane; + mappings[334] = ItemType.GrayStainedGlassPane; + mappings[335] = ItemType.LightGrayStainedGlassPane; + mappings[336] = ItemType.CyanStainedGlassPane; + mappings[337] = ItemType.PurpleStainedGlassPane; + mappings[338] = ItemType.BlueStainedGlassPane; + mappings[339] = ItemType.BrownStainedGlassPane; + mappings[340] = ItemType.GreenStainedGlassPane; + mappings[341] = ItemType.RedStainedGlassPane; + mappings[342] = ItemType.BlackStainedGlassPane; + mappings[343] = ItemType.Prismarine; + mappings[344] = ItemType.PrismarineBricks; + mappings[345] = ItemType.DarkPrismarine; + mappings[346] = ItemType.PrismarineStairs; + mappings[347] = ItemType.PrismarineBrickStairs; + mappings[348] = ItemType.DarkPrismarineStairs; + mappings[349] = ItemType.SeaLantern; + mappings[350] = ItemType.RedSandstone; + mappings[351] = ItemType.ChiseledRedSandstone; + mappings[352] = ItemType.CutRedSandstone; + mappings[353] = ItemType.RedSandstoneStairs; + mappings[354] = ItemType.RepeatingCommandBlock; + mappings[355] = ItemType.ChainCommandBlock; + mappings[356] = ItemType.MagmaBlock; + mappings[357] = ItemType.NetherWartBlock; + mappings[358] = ItemType.RedNetherBricks; + mappings[359] = ItemType.BoneBlock; + mappings[360] = ItemType.StructureVoid; + mappings[361] = ItemType.Observer; + mappings[362] = ItemType.ShulkerBox; + mappings[363] = ItemType.WhiteShulkerBox; + mappings[364] = ItemType.OrangeShulkerBox; + mappings[365] = ItemType.MagentaShulkerBox; + mappings[366] = ItemType.LightBlueShulkerBox; + mappings[367] = ItemType.YellowShulkerBox; + mappings[368] = ItemType.LimeShulkerBox; + mappings[369] = ItemType.PinkShulkerBox; + mappings[370] = ItemType.GrayShulkerBox; + mappings[371] = ItemType.LightGrayShulkerBox; + mappings[372] = ItemType.CyanShulkerBox; + mappings[373] = ItemType.PurpleShulkerBox; + mappings[374] = ItemType.BlueShulkerBox; + mappings[375] = ItemType.BrownShulkerBox; + mappings[376] = ItemType.GreenShulkerBox; + mappings[377] = ItemType.RedShulkerBox; + mappings[378] = ItemType.BlackShulkerBox; + mappings[379] = ItemType.WhiteGlazedTerracotta; + mappings[380] = ItemType.OrangeGlazedTerracotta; + mappings[381] = ItemType.MagentaGlazedTerracotta; + mappings[382] = ItemType.LightBlueGlazedTerracotta; + mappings[383] = ItemType.YellowGlazedTerracotta; + mappings[384] = ItemType.LimeGlazedTerracotta; + mappings[385] = ItemType.PinkGlazedTerracotta; + mappings[386] = ItemType.GrayGlazedTerracotta; + mappings[387] = ItemType.LightGrayGlazedTerracotta; + mappings[388] = ItemType.CyanGlazedTerracotta; + mappings[389] = ItemType.PurpleGlazedTerracotta; + mappings[390] = ItemType.BlueGlazedTerracotta; + mappings[391] = ItemType.BrownGlazedTerracotta; + mappings[392] = ItemType.GreenGlazedTerracotta; + mappings[393] = ItemType.RedGlazedTerracotta; + mappings[394] = ItemType.BlackGlazedTerracotta; + mappings[395] = ItemType.WhiteConcrete; + mappings[396] = ItemType.OrangeConcrete; + mappings[397] = ItemType.MagentaConcrete; + mappings[398] = ItemType.LightBlueConcrete; + mappings[399] = ItemType.YellowConcrete; + mappings[400] = ItemType.LimeConcrete; + mappings[401] = ItemType.PinkConcrete; + mappings[402] = ItemType.GrayConcrete; + mappings[403] = ItemType.LightGrayConcrete; + mappings[404] = ItemType.CyanConcrete; + mappings[405] = ItemType.PurpleConcrete; + mappings[406] = ItemType.BlueConcrete; + mappings[407] = ItemType.BrownConcrete; + mappings[408] = ItemType.GreenConcrete; + mappings[409] = ItemType.RedConcrete; + mappings[410] = ItemType.BlackConcrete; + mappings[411] = ItemType.WhiteConcretePowder; + mappings[412] = ItemType.OrangeConcretePowder; + mappings[413] = ItemType.MagentaConcretePowder; + mappings[414] = ItemType.LightBlueConcretePowder; + mappings[415] = ItemType.YellowConcretePowder; + mappings[416] = ItemType.LimeConcretePowder; + mappings[417] = ItemType.PinkConcretePowder; + mappings[418] = ItemType.GrayConcretePowder; + mappings[419] = ItemType.LightGrayConcretePowder; + mappings[420] = ItemType.CyanConcretePowder; + mappings[421] = ItemType.PurpleConcretePowder; + mappings[422] = ItemType.BlueConcretePowder; + mappings[423] = ItemType.BrownConcretePowder; + mappings[424] = ItemType.GreenConcretePowder; + mappings[425] = ItemType.RedConcretePowder; + mappings[426] = ItemType.BlackConcretePowder; + mappings[427] = ItemType.TurtleEgg; + mappings[428] = ItemType.DeadTubeCoralBlock; + mappings[429] = ItemType.DeadBrainCoralBlock; + mappings[430] = ItemType.DeadBubbleCoralBlock; + mappings[431] = ItemType.DeadFireCoralBlock; + mappings[432] = ItemType.DeadHornCoralBlock; + mappings[433] = ItemType.TubeCoralBlock; + mappings[434] = ItemType.BrainCoralBlock; + mappings[435] = ItemType.BubbleCoralBlock; + mappings[436] = ItemType.FireCoralBlock; + mappings[437] = ItemType.HornCoralBlock; + mappings[438] = ItemType.TubeCoral; + mappings[439] = ItemType.BrainCoral; + mappings[440] = ItemType.BubbleCoral; + mappings[441] = ItemType.FireCoral; + mappings[442] = ItemType.HornCoral; + mappings[443] = ItemType.DeadBrainCoral; + mappings[444] = ItemType.DeadBubbleCoral; + mappings[445] = ItemType.DeadFireCoral; + mappings[446] = ItemType.DeadHornCoral; + mappings[447] = ItemType.DeadTubeCoral; + mappings[448] = ItemType.TubeCoralFan; + mappings[449] = ItemType.BrainCoralFan; + mappings[450] = ItemType.BubbleCoralFan; + mappings[451] = ItemType.FireCoralFan; + mappings[452] = ItemType.HornCoralFan; + mappings[453] = ItemType.DeadTubeCoralFan; + mappings[454] = ItemType.DeadBrainCoralFan; + mappings[455] = ItemType.DeadBubbleCoralFan; + mappings[456] = ItemType.DeadFireCoralFan; + mappings[457] = ItemType.DeadHornCoralFan; + mappings[458] = ItemType.BlueIce; + mappings[459] = ItemType.Conduit; + mappings[460] = ItemType.IronDoor; + mappings[461] = ItemType.OakDoor; + mappings[462] = ItemType.SpruceDoor; + mappings[463] = ItemType.BirchDoor; + mappings[464] = ItemType.JungleDoor; + mappings[465] = ItemType.AcaciaDoor; + mappings[466] = ItemType.DarkOakDoor; + mappings[467] = ItemType.Repeater; + mappings[468] = ItemType.Comparator; + mappings[469] = ItemType.StructureBlock; + mappings[470] = ItemType.TurtleHelmet; + mappings[471] = ItemType.TurtleScute; + mappings[472] = ItemType.IronShovel; + mappings[473] = ItemType.IronPickaxe; + mappings[474] = ItemType.IronAxe; + mappings[475] = ItemType.FlintAndSteel; + mappings[476] = ItemType.Apple; + mappings[477] = ItemType.Bow; + mappings[478] = ItemType.Arrow; + mappings[479] = ItemType.Coal; + mappings[480] = ItemType.Charcoal; + mappings[481] = ItemType.Diamond; + mappings[482] = ItemType.IronIngot; + mappings[483] = ItemType.GoldIngot; + mappings[484] = ItemType.IronSword; + mappings[485] = ItemType.WoodenSword; + mappings[486] = ItemType.WoodenShovel; + mappings[487] = ItemType.WoodenPickaxe; + mappings[488] = ItemType.WoodenAxe; + mappings[489] = ItemType.StoneSword; + mappings[490] = ItemType.StoneShovel; + mappings[491] = ItemType.StonePickaxe; + mappings[492] = ItemType.StoneAxe; + mappings[493] = ItemType.DiamondSword; + mappings[494] = ItemType.DiamondShovel; + mappings[495] = ItemType.DiamondPickaxe; + mappings[496] = ItemType.DiamondAxe; + mappings[497] = ItemType.Stick; + mappings[498] = ItemType.Bowl; + mappings[499] = ItemType.MushroomStew; + mappings[500] = ItemType.GoldenSword; + mappings[501] = ItemType.GoldenShovel; + mappings[502] = ItemType.GoldenPickaxe; + mappings[503] = ItemType.GoldenAxe; + mappings[504] = ItemType.String; + mappings[505] = ItemType.Feather; + mappings[506] = ItemType.Gunpowder; + mappings[507] = ItemType.WoodenHoe; + mappings[508] = ItemType.StoneHoe; + mappings[509] = ItemType.IronHoe; + mappings[510] = ItemType.DiamondHoe; + mappings[511] = ItemType.GoldenHoe; + mappings[512] = ItemType.WheatSeeds; + mappings[513] = ItemType.Wheat; + mappings[514] = ItemType.Bread; + mappings[515] = ItemType.LeatherHelmet; + mappings[516] = ItemType.LeatherChestplate; + mappings[517] = ItemType.LeatherLeggings; + mappings[518] = ItemType.LeatherBoots; + mappings[519] = ItemType.ChainmailHelmet; + mappings[520] = ItemType.ChainmailChestplate; + mappings[521] = ItemType.ChainmailLeggings; + mappings[522] = ItemType.ChainmailBoots; + mappings[523] = ItemType.IronHelmet; + mappings[524] = ItemType.IronChestplate; + mappings[525] = ItemType.IronLeggings; + mappings[526] = ItemType.IronBoots; + mappings[527] = ItemType.DiamondHelmet; + mappings[528] = ItemType.DiamondChestplate; + mappings[529] = ItemType.DiamondLeggings; + mappings[530] = ItemType.DiamondBoots; + mappings[531] = ItemType.GoldenHelmet; + mappings[532] = ItemType.GoldenChestplate; + mappings[533] = ItemType.GoldenLeggings; + mappings[534] = ItemType.GoldenBoots; + mappings[535] = ItemType.Flint; + mappings[536] = ItemType.Porkchop; + mappings[537] = ItemType.CookedPorkchop; + mappings[538] = ItemType.Painting; + mappings[539] = ItemType.GoldenApple; + mappings[540] = ItemType.EnchantedGoldenApple; + mappings[541] = ItemType.OakSign; + mappings[542] = ItemType.Bucket; + mappings[543] = ItemType.WaterBucket; + mappings[544] = ItemType.LavaBucket; + mappings[545] = ItemType.Minecart; + mappings[546] = ItemType.Saddle; + mappings[547] = ItemType.Redstone; + mappings[548] = ItemType.Snowball; + mappings[549] = ItemType.OakBoat; + mappings[550] = ItemType.Leather; + mappings[551] = ItemType.MilkBucket; + mappings[552] = ItemType.PufferfishBucket; + mappings[553] = ItemType.SalmonBucket; + mappings[554] = ItemType.CodBucket; + mappings[555] = ItemType.TropicalFishBucket; + mappings[556] = ItemType.Brick; + mappings[557] = ItemType.ClayBall; + mappings[558] = ItemType.SugarCane; + mappings[559] = ItemType.Kelp; + mappings[560] = ItemType.DriedKelpBlock; + mappings[561] = ItemType.Paper; + mappings[562] = ItemType.Book; + mappings[563] = ItemType.SlimeBall; + mappings[564] = ItemType.ChestMinecart; + mappings[565] = ItemType.FurnaceMinecart; + mappings[566] = ItemType.Egg; + mappings[567] = ItemType.Compass; + mappings[568] = ItemType.FishingRod; + mappings[569] = ItemType.Clock; + mappings[570] = ItemType.GlowstoneDust; + mappings[571] = ItemType.Cod; + mappings[572] = ItemType.Salmon; + mappings[573] = ItemType.TropicalFish; + mappings[574] = ItemType.Pufferfish; + mappings[575] = ItemType.CookedCod; + mappings[576] = ItemType.CookedSalmon; + mappings[577] = ItemType.InkSac; + mappings[578] = ItemType.RedDye; + mappings[579] = ItemType.GreenDye; + mappings[580] = ItemType.CocoaBeans; + mappings[581] = ItemType.LapisLazuli; + mappings[582] = ItemType.PurpleDye; + mappings[583] = ItemType.CyanDye; + mappings[584] = ItemType.LightGrayDye; + mappings[585] = ItemType.GrayDye; + mappings[586] = ItemType.PinkDye; + mappings[587] = ItemType.LimeDye; + mappings[588] = ItemType.YellowDye; + mappings[589] = ItemType.LightBlueDye; + mappings[590] = ItemType.MagentaDye; + mappings[591] = ItemType.OrangeDye; + mappings[592] = ItemType.BoneMeal; + mappings[593] = ItemType.Bone; + mappings[594] = ItemType.Sugar; + mappings[595] = ItemType.Cake; + mappings[596] = ItemType.WhiteBed; + mappings[597] = ItemType.OrangeBed; + mappings[598] = ItemType.MagentaBed; + mappings[599] = ItemType.LightBlueBed; + mappings[600] = ItemType.YellowBed; + mappings[601] = ItemType.LimeBed; + mappings[602] = ItemType.PinkBed; + mappings[603] = ItemType.GrayBed; + mappings[604] = ItemType.LightGrayBed; + mappings[605] = ItemType.CyanBed; + mappings[606] = ItemType.PurpleBed; + mappings[607] = ItemType.BlueBed; + mappings[608] = ItemType.BrownBed; + mappings[609] = ItemType.GreenBed; + mappings[610] = ItemType.RedBed; + mappings[611] = ItemType.BlackBed; + mappings[612] = ItemType.Cookie; + mappings[613] = ItemType.FilledMap; + mappings[614] = ItemType.Shears; + mappings[615] = ItemType.MelonSlice; + mappings[616] = ItemType.DriedKelp; + mappings[617] = ItemType.PumpkinSeeds; + mappings[618] = ItemType.MelonSeeds; + mappings[619] = ItemType.Beef; + mappings[620] = ItemType.CookedBeef; + mappings[621] = ItemType.Chicken; + mappings[622] = ItemType.CookedChicken; + mappings[623] = ItemType.RottenFlesh; + mappings[624] = ItemType.EnderPearl; + mappings[625] = ItemType.BlazeRod; + mappings[626] = ItemType.GhastTear; + mappings[627] = ItemType.GoldNugget; + mappings[628] = ItemType.NetherWart; + mappings[629] = ItemType.Potion; + mappings[630] = ItemType.GlassBottle; + mappings[631] = ItemType.SpiderEye; + mappings[632] = ItemType.FermentedSpiderEye; + mappings[633] = ItemType.BlazePowder; + mappings[634] = ItemType.MagmaCream; + mappings[635] = ItemType.BrewingStand; + mappings[636] = ItemType.Cauldron; + mappings[637] = ItemType.EnderEye; + mappings[638] = ItemType.GlisteringMelonSlice; + mappings[639] = ItemType.BatSpawnEgg; + mappings[640] = ItemType.BlazeSpawnEgg; + mappings[641] = ItemType.CaveSpiderSpawnEgg; + mappings[642] = ItemType.ChickenSpawnEgg; + mappings[643] = ItemType.CodSpawnEgg; + mappings[644] = ItemType.CowSpawnEgg; + mappings[645] = ItemType.CreeperSpawnEgg; + mappings[646] = ItemType.DolphinSpawnEgg; + mappings[647] = ItemType.DonkeySpawnEgg; + mappings[648] = ItemType.DrownedSpawnEgg; + mappings[649] = ItemType.ElderGuardianSpawnEgg; + mappings[650] = ItemType.EndermanSpawnEgg; + mappings[651] = ItemType.EndermiteSpawnEgg; + mappings[652] = ItemType.EvokerSpawnEgg; + mappings[653] = ItemType.GhastSpawnEgg; + mappings[654] = ItemType.GuardianSpawnEgg; + mappings[655] = ItemType.HorseSpawnEgg; + mappings[656] = ItemType.HuskSpawnEgg; + mappings[657] = ItemType.LlamaSpawnEgg; + mappings[658] = ItemType.MagmaCubeSpawnEgg; + mappings[659] = ItemType.MooshroomSpawnEgg; + mappings[660] = ItemType.MuleSpawnEgg; + mappings[661] = ItemType.OcelotSpawnEgg; + mappings[662] = ItemType.ParrotSpawnEgg; + mappings[663] = ItemType.PhantomSpawnEgg; + mappings[664] = ItemType.PigSpawnEgg; + mappings[665] = ItemType.PolarBearSpawnEgg; + mappings[666] = ItemType.PufferfishSpawnEgg; + mappings[667] = ItemType.RabbitSpawnEgg; + mappings[668] = ItemType.SalmonSpawnEgg; + mappings[669] = ItemType.SheepSpawnEgg; + mappings[670] = ItemType.ShulkerSpawnEgg; + mappings[671] = ItemType.SilverfishSpawnEgg; + mappings[672] = ItemType.SkeletonSpawnEgg; + mappings[673] = ItemType.SkeletonHorseSpawnEgg; + mappings[674] = ItemType.SlimeSpawnEgg; + mappings[675] = ItemType.SpiderSpawnEgg; + mappings[676] = ItemType.SquidSpawnEgg; + mappings[677] = ItemType.StraySpawnEgg; + mappings[678] = ItemType.TropicalFishSpawnEgg; + mappings[679] = ItemType.TurtleSpawnEgg; + mappings[680] = ItemType.VexSpawnEgg; + mappings[681] = ItemType.VillagerSpawnEgg; + mappings[682] = ItemType.VindicatorSpawnEgg; + mappings[683] = ItemType.WitchSpawnEgg; + mappings[684] = ItemType.WitherSkeletonSpawnEgg; + mappings[685] = ItemType.WolfSpawnEgg; + mappings[686] = ItemType.ZombieSpawnEgg; + mappings[687] = ItemType.ZombieHorseSpawnEgg; + mappings[688] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[689] = ItemType.ZombieVillagerSpawnEgg; + mappings[690] = ItemType.ExperienceBottle; + mappings[691] = ItemType.FireCharge; + mappings[692] = ItemType.WritableBook; + mappings[693] = ItemType.WrittenBook; + mappings[694] = ItemType.Emerald; + mappings[695] = ItemType.ItemFrame; + mappings[696] = ItemType.FlowerPot; + mappings[697] = ItemType.Carrot; + mappings[698] = ItemType.Potato; + mappings[699] = ItemType.BakedPotato; + mappings[700] = ItemType.PoisonousPotato; + mappings[701] = ItemType.Map; + mappings[702] = ItemType.GoldenCarrot; + mappings[703] = ItemType.SkeletonSkull; + mappings[704] = ItemType.WitherSkeletonSkull; + mappings[705] = ItemType.PlayerHead; + mappings[706] = ItemType.ZombieHead; + mappings[707] = ItemType.CreeperHead; + mappings[708] = ItemType.DragonHead; + mappings[709] = ItemType.CarrotOnAStick; + mappings[710] = ItemType.NetherStar; + mappings[711] = ItemType.PumpkinPie; + mappings[712] = ItemType.FireworkRocket; + mappings[713] = ItemType.FireworkStar; + mappings[714] = ItemType.EnchantedBook; + mappings[715] = ItemType.NetherBrick; + mappings[716] = ItemType.Quartz; + mappings[717] = ItemType.TntMinecart; + mappings[718] = ItemType.HopperMinecart; + mappings[719] = ItemType.PrismarineShard; + mappings[720] = ItemType.PrismarineCrystals; + mappings[721] = ItemType.Rabbit; + mappings[722] = ItemType.CookedRabbit; + mappings[723] = ItemType.RabbitStew; + mappings[724] = ItemType.RabbitFoot; + mappings[725] = ItemType.RabbitHide; + mappings[726] = ItemType.ArmorStand; + mappings[727] = ItemType.IronHorseArmor; + mappings[728] = ItemType.GoldenHorseArmor; + mappings[729] = ItemType.DiamondHorseArmor; + mappings[730] = ItemType.Lead; + mappings[731] = ItemType.NameTag; + mappings[732] = ItemType.CommandBlockMinecart; + mappings[733] = ItemType.Mutton; + mappings[734] = ItemType.CookedMutton; + mappings[735] = ItemType.WhiteBanner; + mappings[736] = ItemType.OrangeBanner; + mappings[737] = ItemType.MagentaBanner; + mappings[738] = ItemType.LightBlueBanner; + mappings[739] = ItemType.YellowBanner; + mappings[740] = ItemType.LimeBanner; + mappings[741] = ItemType.PinkBanner; + mappings[742] = ItemType.GrayBanner; + mappings[743] = ItemType.LightGrayBanner; + mappings[744] = ItemType.CyanBanner; + mappings[745] = ItemType.PurpleBanner; + mappings[746] = ItemType.BlueBanner; + mappings[747] = ItemType.BrownBanner; + mappings[748] = ItemType.GreenBanner; + mappings[749] = ItemType.RedBanner; + mappings[750] = ItemType.BlackBanner; + mappings[751] = ItemType.EndCrystal; + mappings[752] = ItemType.ChorusFruit; + mappings[753] = ItemType.PoppedChorusFruit; + mappings[754] = ItemType.Beetroot; + mappings[755] = ItemType.BeetrootSeeds; + mappings[756] = ItemType.BeetrootSoup; + mappings[757] = ItemType.DragonBreath; + mappings[758] = ItemType.SplashPotion; + mappings[759] = ItemType.SpectralArrow; + mappings[760] = ItemType.TippedArrow; + mappings[761] = ItemType.LingeringPotion; + mappings[762] = ItemType.Shield; + mappings[763] = ItemType.Elytra; + mappings[764] = ItemType.SpruceBoat; + mappings[765] = ItemType.BirchBoat; + mappings[766] = ItemType.JungleBoat; + mappings[767] = ItemType.AcaciaBoat; + mappings[768] = ItemType.DarkOakBoat; + mappings[769] = ItemType.TotemOfUndying; + mappings[770] = ItemType.ShulkerShell; + mappings[771] = ItemType.IronNugget; + mappings[772] = ItemType.KnowledgeBook; + mappings[773] = ItemType.DebugStick; + mappings[774] = ItemType.MusicDisc13; + mappings[775] = ItemType.MusicDiscCat; + mappings[776] = ItemType.MusicDiscBlocks; + mappings[777] = ItemType.MusicDiscChirp; + mappings[778] = ItemType.MusicDiscFar; + mappings[779] = ItemType.MusicDiscMall; + mappings[780] = ItemType.MusicDiscMellohi; + mappings[781] = ItemType.MusicDiscStal; + mappings[782] = ItemType.MusicDiscStrad; + mappings[783] = ItemType.MusicDiscWard; + mappings[784] = ItemType.MusicDisc11; + mappings[785] = ItemType.MusicDiscWait; + mappings[786] = ItemType.Trident; + mappings[787] = ItemType.PhantomMembrane; + mappings[788] = ItemType.NautilusShell; + mappings[789] = ItemType.HeartOfTheSea; + } protected override Dictionary<int, ItemType> GetDict() { diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs index c4c02a09..c84079da 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette114.cs @@ -2,17 +2,890 @@ using System.Collections.Generic; namespace MinecraftClient.Inventory.ItemPalettes { - /// <summary> - /// Minimal flattened item palette for 1.14 book handling. - /// </summary> public class ItemPalette114 : ItemPalette { - private static readonly Dictionary<int, ItemType> mappings = new() + private static readonly Dictionary<int, ItemType> mappings = new(); + + static ItemPalette114() { - [0] = ItemType.Air, - [757] = ItemType.WritableBook, - [758] = ItemType.WrittenBook - }; + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.GrassBlock; + mappings[9] = ItemType.Dirt; + mappings[10] = ItemType.CoarseDirt; + mappings[11] = ItemType.Podzol; + mappings[12] = ItemType.Cobblestone; + mappings[13] = ItemType.OakPlanks; + mappings[14] = ItemType.SprucePlanks; + mappings[15] = ItemType.BirchPlanks; + mappings[16] = ItemType.JunglePlanks; + mappings[17] = ItemType.AcaciaPlanks; + mappings[18] = ItemType.DarkOakPlanks; + mappings[19] = ItemType.OakSapling; + mappings[20] = ItemType.SpruceSapling; + mappings[21] = ItemType.BirchSapling; + mappings[22] = ItemType.JungleSapling; + mappings[23] = ItemType.AcaciaSapling; + mappings[24] = ItemType.DarkOakSapling; + mappings[25] = ItemType.Bedrock; + mappings[26] = ItemType.Sand; + mappings[27] = ItemType.RedSand; + mappings[28] = ItemType.Gravel; + mappings[29] = ItemType.GoldOre; + mappings[30] = ItemType.IronOre; + mappings[31] = ItemType.CoalOre; + mappings[32] = ItemType.OakLog; + mappings[33] = ItemType.SpruceLog; + mappings[34] = ItemType.BirchLog; + mappings[35] = ItemType.JungleLog; + mappings[36] = ItemType.AcaciaLog; + mappings[37] = ItemType.DarkOakLog; + mappings[38] = ItemType.StrippedOakLog; + mappings[39] = ItemType.StrippedSpruceLog; + mappings[40] = ItemType.StrippedBirchLog; + mappings[41] = ItemType.StrippedJungleLog; + mappings[42] = ItemType.StrippedAcaciaLog; + mappings[43] = ItemType.StrippedDarkOakLog; + mappings[44] = ItemType.StrippedOakWood; + mappings[45] = ItemType.StrippedSpruceWood; + mappings[46] = ItemType.StrippedBirchWood; + mappings[47] = ItemType.StrippedJungleWood; + mappings[48] = ItemType.StrippedAcaciaWood; + mappings[49] = ItemType.StrippedDarkOakWood; + mappings[50] = ItemType.OakWood; + mappings[51] = ItemType.SpruceWood; + mappings[52] = ItemType.BirchWood; + mappings[53] = ItemType.JungleWood; + mappings[54] = ItemType.AcaciaWood; + mappings[55] = ItemType.DarkOakWood; + mappings[56] = ItemType.OakLeaves; + mappings[57] = ItemType.SpruceLeaves; + mappings[58] = ItemType.BirchLeaves; + mappings[59] = ItemType.JungleLeaves; + mappings[60] = ItemType.AcaciaLeaves; + mappings[61] = ItemType.DarkOakLeaves; + mappings[62] = ItemType.Sponge; + mappings[63] = ItemType.WetSponge; + mappings[64] = ItemType.Glass; + mappings[65] = ItemType.LapisOre; + mappings[66] = ItemType.LapisBlock; + mappings[67] = ItemType.Dispenser; + mappings[68] = ItemType.Sandstone; + mappings[69] = ItemType.ChiseledSandstone; + mappings[70] = ItemType.CutSandstone; + mappings[71] = ItemType.NoteBlock; + mappings[72] = ItemType.PoweredRail; + mappings[73] = ItemType.DetectorRail; + mappings[74] = ItemType.StickyPiston; + mappings[75] = ItemType.Cobweb; + mappings[76] = ItemType.ShortGrass; + mappings[77] = ItemType.Fern; + mappings[78] = ItemType.DeadBush; + mappings[79] = ItemType.Seagrass; + mappings[80] = ItemType.SeaPickle; + mappings[81] = ItemType.Piston; + mappings[82] = ItemType.WhiteWool; + mappings[83] = ItemType.OrangeWool; + mappings[84] = ItemType.MagentaWool; + mappings[85] = ItemType.LightBlueWool; + mappings[86] = ItemType.YellowWool; + mappings[87] = ItemType.LimeWool; + mappings[88] = ItemType.PinkWool; + mappings[89] = ItemType.GrayWool; + mappings[90] = ItemType.LightGrayWool; + mappings[91] = ItemType.CyanWool; + mappings[92] = ItemType.PurpleWool; + mappings[93] = ItemType.BlueWool; + mappings[94] = ItemType.BrownWool; + mappings[95] = ItemType.GreenWool; + mappings[96] = ItemType.RedWool; + mappings[97] = ItemType.BlackWool; + mappings[98] = ItemType.Dandelion; + mappings[99] = ItemType.Poppy; + mappings[100] = ItemType.BlueOrchid; + mappings[101] = ItemType.Allium; + mappings[102] = ItemType.AzureBluet; + mappings[103] = ItemType.RedTulip; + mappings[104] = ItemType.OrangeTulip; + mappings[105] = ItemType.WhiteTulip; + mappings[106] = ItemType.PinkTulip; + mappings[107] = ItemType.OxeyeDaisy; + mappings[108] = ItemType.Cornflower; + mappings[109] = ItemType.LilyOfTheValley; + mappings[110] = ItemType.WitherRose; + mappings[111] = ItemType.BrownMushroom; + mappings[112] = ItemType.RedMushroom; + mappings[113] = ItemType.GoldBlock; + mappings[114] = ItemType.IronBlock; + mappings[115] = ItemType.OakSlab; + mappings[116] = ItemType.SpruceSlab; + mappings[117] = ItemType.BirchSlab; + mappings[118] = ItemType.JungleSlab; + mappings[119] = ItemType.AcaciaSlab; + mappings[120] = ItemType.DarkOakSlab; + mappings[121] = ItemType.StoneSlab; + mappings[122] = ItemType.SmoothStoneSlab; + mappings[123] = ItemType.SandstoneSlab; + mappings[124] = ItemType.CutSandstoneSlab; + mappings[125] = ItemType.PetrifiedOakSlab; + mappings[126] = ItemType.CobblestoneSlab; + mappings[127] = ItemType.BrickSlab; + mappings[128] = ItemType.StoneBrickSlab; + mappings[129] = ItemType.NetherBrickSlab; + mappings[130] = ItemType.QuartzSlab; + mappings[131] = ItemType.RedSandstoneSlab; + mappings[132] = ItemType.CutRedSandstoneSlab; + mappings[133] = ItemType.PurpurSlab; + mappings[134] = ItemType.PrismarineSlab; + mappings[135] = ItemType.PrismarineBrickSlab; + mappings[136] = ItemType.DarkPrismarineSlab; + mappings[137] = ItemType.SmoothQuartz; + mappings[138] = ItemType.SmoothRedSandstone; + mappings[139] = ItemType.SmoothSandstone; + mappings[140] = ItemType.SmoothStone; + mappings[141] = ItemType.Bricks; + mappings[142] = ItemType.Tnt; + mappings[143] = ItemType.Bookshelf; + mappings[144] = ItemType.MossyCobblestone; + mappings[145] = ItemType.Obsidian; + mappings[146] = ItemType.Torch; + mappings[147] = ItemType.EndRod; + mappings[148] = ItemType.ChorusPlant; + mappings[149] = ItemType.ChorusFlower; + mappings[150] = ItemType.PurpurBlock; + mappings[151] = ItemType.PurpurPillar; + mappings[152] = ItemType.PurpurStairs; + mappings[153] = ItemType.Spawner; + mappings[154] = ItemType.OakStairs; + mappings[155] = ItemType.Chest; + mappings[156] = ItemType.DiamondOre; + mappings[157] = ItemType.DiamondBlock; + mappings[158] = ItemType.CraftingTable; + mappings[159] = ItemType.Farmland; + mappings[160] = ItemType.Furnace; + mappings[161] = ItemType.Ladder; + mappings[162] = ItemType.Rail; + mappings[163] = ItemType.CobblestoneStairs; + mappings[164] = ItemType.Lever; + mappings[165] = ItemType.StonePressurePlate; + mappings[166] = ItemType.OakPressurePlate; + mappings[167] = ItemType.SprucePressurePlate; + mappings[168] = ItemType.BirchPressurePlate; + mappings[169] = ItemType.JunglePressurePlate; + mappings[170] = ItemType.AcaciaPressurePlate; + mappings[171] = ItemType.DarkOakPressurePlate; + mappings[172] = ItemType.RedstoneOre; + mappings[173] = ItemType.RedstoneTorch; + mappings[174] = ItemType.StoneButton; + mappings[175] = ItemType.Snow; + mappings[176] = ItemType.Ice; + mappings[177] = ItemType.SnowBlock; + mappings[178] = ItemType.Cactus; + mappings[179] = ItemType.Clay; + mappings[180] = ItemType.Jukebox; + mappings[181] = ItemType.OakFence; + mappings[182] = ItemType.SpruceFence; + mappings[183] = ItemType.BirchFence; + mappings[184] = ItemType.JungleFence; + mappings[185] = ItemType.AcaciaFence; + mappings[186] = ItemType.DarkOakFence; + mappings[187] = ItemType.Pumpkin; + mappings[188] = ItemType.CarvedPumpkin; + mappings[189] = ItemType.Netherrack; + mappings[190] = ItemType.SoulSand; + mappings[191] = ItemType.Glowstone; + mappings[192] = ItemType.JackOLantern; + mappings[193] = ItemType.OakTrapdoor; + mappings[194] = ItemType.SpruceTrapdoor; + mappings[195] = ItemType.BirchTrapdoor; + mappings[196] = ItemType.JungleTrapdoor; + mappings[197] = ItemType.AcaciaTrapdoor; + mappings[198] = ItemType.DarkOakTrapdoor; + mappings[199] = ItemType.InfestedStone; + mappings[200] = ItemType.InfestedCobblestone; + mappings[201] = ItemType.InfestedStoneBricks; + mappings[202] = ItemType.InfestedMossyStoneBricks; + mappings[203] = ItemType.InfestedCrackedStoneBricks; + mappings[204] = ItemType.InfestedChiseledStoneBricks; + mappings[205] = ItemType.StoneBricks; + mappings[206] = ItemType.MossyStoneBricks; + mappings[207] = ItemType.CrackedStoneBricks; + mappings[208] = ItemType.ChiseledStoneBricks; + mappings[209] = ItemType.BrownMushroomBlock; + mappings[210] = ItemType.RedMushroomBlock; + mappings[211] = ItemType.MushroomStem; + mappings[212] = ItemType.IronBars; + mappings[213] = ItemType.GlassPane; + mappings[214] = ItemType.Melon; + mappings[215] = ItemType.Vine; + mappings[216] = ItemType.OakFenceGate; + mappings[217] = ItemType.SpruceFenceGate; + mappings[218] = ItemType.BirchFenceGate; + mappings[219] = ItemType.JungleFenceGate; + mappings[220] = ItemType.AcaciaFenceGate; + mappings[221] = ItemType.DarkOakFenceGate; + mappings[222] = ItemType.BrickStairs; + mappings[223] = ItemType.StoneBrickStairs; + mappings[224] = ItemType.Mycelium; + mappings[225] = ItemType.LilyPad; + mappings[226] = ItemType.NetherBricks; + mappings[227] = ItemType.NetherBrickFence; + mappings[228] = ItemType.NetherBrickStairs; + mappings[229] = ItemType.EnchantingTable; + mappings[230] = ItemType.EndPortalFrame; + mappings[231] = ItemType.EndStone; + mappings[232] = ItemType.EndStoneBricks; + mappings[233] = ItemType.DragonEgg; + mappings[234] = ItemType.RedstoneLamp; + mappings[235] = ItemType.SandstoneStairs; + mappings[236] = ItemType.EmeraldOre; + mappings[237] = ItemType.EnderChest; + mappings[238] = ItemType.TripwireHook; + mappings[239] = ItemType.EmeraldBlock; + mappings[240] = ItemType.SpruceStairs; + mappings[241] = ItemType.BirchStairs; + mappings[242] = ItemType.JungleStairs; + mappings[243] = ItemType.CommandBlock; + mappings[244] = ItemType.Beacon; + mappings[245] = ItemType.CobblestoneWall; + mappings[246] = ItemType.MossyCobblestoneWall; + mappings[247] = ItemType.BrickWall; + mappings[248] = ItemType.PrismarineWall; + mappings[249] = ItemType.RedSandstoneWall; + mappings[250] = ItemType.MossyStoneBrickWall; + mappings[251] = ItemType.GraniteWall; + mappings[252] = ItemType.StoneBrickWall; + mappings[253] = ItemType.NetherBrickWall; + mappings[254] = ItemType.AndesiteWall; + mappings[255] = ItemType.RedNetherBrickWall; + mappings[256] = ItemType.SandstoneWall; + mappings[257] = ItemType.EndStoneBrickWall; + mappings[258] = ItemType.DioriteWall; + mappings[259] = ItemType.OakButton; + mappings[260] = ItemType.SpruceButton; + mappings[261] = ItemType.BirchButton; + mappings[262] = ItemType.JungleButton; + mappings[263] = ItemType.AcaciaButton; + mappings[264] = ItemType.DarkOakButton; + mappings[265] = ItemType.Anvil; + mappings[266] = ItemType.ChippedAnvil; + mappings[267] = ItemType.DamagedAnvil; + mappings[268] = ItemType.TrappedChest; + mappings[269] = ItemType.LightWeightedPressurePlate; + mappings[270] = ItemType.HeavyWeightedPressurePlate; + mappings[271] = ItemType.DaylightDetector; + mappings[272] = ItemType.RedstoneBlock; + mappings[273] = ItemType.NetherQuartzOre; + mappings[274] = ItemType.Hopper; + mappings[275] = ItemType.ChiseledQuartzBlock; + mappings[276] = ItemType.QuartzBlock; + mappings[277] = ItemType.QuartzPillar; + mappings[278] = ItemType.QuartzStairs; + mappings[279] = ItemType.ActivatorRail; + mappings[280] = ItemType.Dropper; + mappings[281] = ItemType.WhiteTerracotta; + mappings[282] = ItemType.OrangeTerracotta; + mappings[283] = ItemType.MagentaTerracotta; + mappings[284] = ItemType.LightBlueTerracotta; + mappings[285] = ItemType.YellowTerracotta; + mappings[286] = ItemType.LimeTerracotta; + mappings[287] = ItemType.PinkTerracotta; + mappings[288] = ItemType.GrayTerracotta; + mappings[289] = ItemType.LightGrayTerracotta; + mappings[290] = ItemType.CyanTerracotta; + mappings[291] = ItemType.PurpleTerracotta; + mappings[292] = ItemType.BlueTerracotta; + mappings[293] = ItemType.BrownTerracotta; + mappings[294] = ItemType.GreenTerracotta; + mappings[295] = ItemType.RedTerracotta; + mappings[296] = ItemType.BlackTerracotta; + mappings[297] = ItemType.Barrier; + mappings[298] = ItemType.IronTrapdoor; + mappings[299] = ItemType.HayBlock; + mappings[300] = ItemType.WhiteCarpet; + mappings[301] = ItemType.OrangeCarpet; + mappings[302] = ItemType.MagentaCarpet; + mappings[303] = ItemType.LightBlueCarpet; + mappings[304] = ItemType.YellowCarpet; + mappings[305] = ItemType.LimeCarpet; + mappings[306] = ItemType.PinkCarpet; + mappings[307] = ItemType.GrayCarpet; + mappings[308] = ItemType.LightGrayCarpet; + mappings[309] = ItemType.CyanCarpet; + mappings[310] = ItemType.PurpleCarpet; + mappings[311] = ItemType.BlueCarpet; + mappings[312] = ItemType.BrownCarpet; + mappings[313] = ItemType.GreenCarpet; + mappings[314] = ItemType.RedCarpet; + mappings[315] = ItemType.BlackCarpet; + mappings[316] = ItemType.Terracotta; + mappings[317] = ItemType.CoalBlock; + mappings[318] = ItemType.PackedIce; + mappings[319] = ItemType.AcaciaStairs; + mappings[320] = ItemType.DarkOakStairs; + mappings[321] = ItemType.SlimeBlock; + mappings[322] = ItemType.DirtPath; + mappings[323] = ItemType.Sunflower; + mappings[324] = ItemType.Lilac; + mappings[325] = ItemType.RoseBush; + mappings[326] = ItemType.Peony; + mappings[327] = ItemType.TallGrass; + mappings[328] = ItemType.LargeFern; + mappings[329] = ItemType.WhiteStainedGlass; + mappings[330] = ItemType.OrangeStainedGlass; + mappings[331] = ItemType.MagentaStainedGlass; + mappings[332] = ItemType.LightBlueStainedGlass; + mappings[333] = ItemType.YellowStainedGlass; + mappings[334] = ItemType.LimeStainedGlass; + mappings[335] = ItemType.PinkStainedGlass; + mappings[336] = ItemType.GrayStainedGlass; + mappings[337] = ItemType.LightGrayStainedGlass; + mappings[338] = ItemType.CyanStainedGlass; + mappings[339] = ItemType.PurpleStainedGlass; + mappings[340] = ItemType.BlueStainedGlass; + mappings[341] = ItemType.BrownStainedGlass; + mappings[342] = ItemType.GreenStainedGlass; + mappings[343] = ItemType.RedStainedGlass; + mappings[344] = ItemType.BlackStainedGlass; + mappings[345] = ItemType.WhiteStainedGlassPane; + mappings[346] = ItemType.OrangeStainedGlassPane; + mappings[347] = ItemType.MagentaStainedGlassPane; + mappings[348] = ItemType.LightBlueStainedGlassPane; + mappings[349] = ItemType.YellowStainedGlassPane; + mappings[350] = ItemType.LimeStainedGlassPane; + mappings[351] = ItemType.PinkStainedGlassPane; + mappings[352] = ItemType.GrayStainedGlassPane; + mappings[353] = ItemType.LightGrayStainedGlassPane; + mappings[354] = ItemType.CyanStainedGlassPane; + mappings[355] = ItemType.PurpleStainedGlassPane; + mappings[356] = ItemType.BlueStainedGlassPane; + mappings[357] = ItemType.BrownStainedGlassPane; + mappings[358] = ItemType.GreenStainedGlassPane; + mappings[359] = ItemType.RedStainedGlassPane; + mappings[360] = ItemType.BlackStainedGlassPane; + mappings[361] = ItemType.Prismarine; + mappings[362] = ItemType.PrismarineBricks; + mappings[363] = ItemType.DarkPrismarine; + mappings[364] = ItemType.PrismarineStairs; + mappings[365] = ItemType.PrismarineBrickStairs; + mappings[366] = ItemType.DarkPrismarineStairs; + mappings[367] = ItemType.SeaLantern; + mappings[368] = ItemType.RedSandstone; + mappings[369] = ItemType.ChiseledRedSandstone; + mappings[370] = ItemType.CutRedSandstone; + mappings[371] = ItemType.RedSandstoneStairs; + mappings[372] = ItemType.RepeatingCommandBlock; + mappings[373] = ItemType.ChainCommandBlock; + mappings[374] = ItemType.MagmaBlock; + mappings[375] = ItemType.NetherWartBlock; + mappings[376] = ItemType.RedNetherBricks; + mappings[377] = ItemType.BoneBlock; + mappings[378] = ItemType.StructureVoid; + mappings[379] = ItemType.Observer; + mappings[380] = ItemType.ShulkerBox; + mappings[381] = ItemType.WhiteShulkerBox; + mappings[382] = ItemType.OrangeShulkerBox; + mappings[383] = ItemType.MagentaShulkerBox; + mappings[384] = ItemType.LightBlueShulkerBox; + mappings[385] = ItemType.YellowShulkerBox; + mappings[386] = ItemType.LimeShulkerBox; + mappings[387] = ItemType.PinkShulkerBox; + mappings[388] = ItemType.GrayShulkerBox; + mappings[389] = ItemType.LightGrayShulkerBox; + mappings[390] = ItemType.CyanShulkerBox; + mappings[391] = ItemType.PurpleShulkerBox; + mappings[392] = ItemType.BlueShulkerBox; + mappings[393] = ItemType.BrownShulkerBox; + mappings[394] = ItemType.GreenShulkerBox; + mappings[395] = ItemType.RedShulkerBox; + mappings[396] = ItemType.BlackShulkerBox; + mappings[397] = ItemType.WhiteGlazedTerracotta; + mappings[398] = ItemType.OrangeGlazedTerracotta; + mappings[399] = ItemType.MagentaGlazedTerracotta; + mappings[400] = ItemType.LightBlueGlazedTerracotta; + mappings[401] = ItemType.YellowGlazedTerracotta; + mappings[402] = ItemType.LimeGlazedTerracotta; + mappings[403] = ItemType.PinkGlazedTerracotta; + mappings[404] = ItemType.GrayGlazedTerracotta; + mappings[405] = ItemType.LightGrayGlazedTerracotta; + mappings[406] = ItemType.CyanGlazedTerracotta; + mappings[407] = ItemType.PurpleGlazedTerracotta; + mappings[408] = ItemType.BlueGlazedTerracotta; + mappings[409] = ItemType.BrownGlazedTerracotta; + mappings[410] = ItemType.GreenGlazedTerracotta; + mappings[411] = ItemType.RedGlazedTerracotta; + mappings[412] = ItemType.BlackGlazedTerracotta; + mappings[413] = ItemType.WhiteConcrete; + mappings[414] = ItemType.OrangeConcrete; + mappings[415] = ItemType.MagentaConcrete; + mappings[416] = ItemType.LightBlueConcrete; + mappings[417] = ItemType.YellowConcrete; + mappings[418] = ItemType.LimeConcrete; + mappings[419] = ItemType.PinkConcrete; + mappings[420] = ItemType.GrayConcrete; + mappings[421] = ItemType.LightGrayConcrete; + mappings[422] = ItemType.CyanConcrete; + mappings[423] = ItemType.PurpleConcrete; + mappings[424] = ItemType.BlueConcrete; + mappings[425] = ItemType.BrownConcrete; + mappings[426] = ItemType.GreenConcrete; + mappings[427] = ItemType.RedConcrete; + mappings[428] = ItemType.BlackConcrete; + mappings[429] = ItemType.WhiteConcretePowder; + mappings[430] = ItemType.OrangeConcretePowder; + mappings[431] = ItemType.MagentaConcretePowder; + mappings[432] = ItemType.LightBlueConcretePowder; + mappings[433] = ItemType.YellowConcretePowder; + mappings[434] = ItemType.LimeConcretePowder; + mappings[435] = ItemType.PinkConcretePowder; + mappings[436] = ItemType.GrayConcretePowder; + mappings[437] = ItemType.LightGrayConcretePowder; + mappings[438] = ItemType.CyanConcretePowder; + mappings[439] = ItemType.PurpleConcretePowder; + mappings[440] = ItemType.BlueConcretePowder; + mappings[441] = ItemType.BrownConcretePowder; + mappings[442] = ItemType.GreenConcretePowder; + mappings[443] = ItemType.RedConcretePowder; + mappings[444] = ItemType.BlackConcretePowder; + mappings[445] = ItemType.TurtleEgg; + mappings[446] = ItemType.DeadTubeCoralBlock; + mappings[447] = ItemType.DeadBrainCoralBlock; + mappings[448] = ItemType.DeadBubbleCoralBlock; + mappings[449] = ItemType.DeadFireCoralBlock; + mappings[450] = ItemType.DeadHornCoralBlock; + mappings[451] = ItemType.TubeCoralBlock; + mappings[452] = ItemType.BrainCoralBlock; + mappings[453] = ItemType.BubbleCoralBlock; + mappings[454] = ItemType.FireCoralBlock; + mappings[455] = ItemType.HornCoralBlock; + mappings[456] = ItemType.TubeCoral; + mappings[457] = ItemType.BrainCoral; + mappings[458] = ItemType.BubbleCoral; + mappings[459] = ItemType.FireCoral; + mappings[460] = ItemType.HornCoral; + mappings[461] = ItemType.DeadBrainCoral; + mappings[462] = ItemType.DeadBubbleCoral; + mappings[463] = ItemType.DeadFireCoral; + mappings[464] = ItemType.DeadHornCoral; + mappings[465] = ItemType.DeadTubeCoral; + mappings[466] = ItemType.TubeCoralFan; + mappings[467] = ItemType.BrainCoralFan; + mappings[468] = ItemType.BubbleCoralFan; + mappings[469] = ItemType.FireCoralFan; + mappings[470] = ItemType.HornCoralFan; + mappings[471] = ItemType.DeadTubeCoralFan; + mappings[472] = ItemType.DeadBrainCoralFan; + mappings[473] = ItemType.DeadBubbleCoralFan; + mappings[474] = ItemType.DeadFireCoralFan; + mappings[475] = ItemType.DeadHornCoralFan; + mappings[476] = ItemType.BlueIce; + mappings[477] = ItemType.Conduit; + mappings[478] = ItemType.PolishedGraniteStairs; + mappings[479] = ItemType.SmoothRedSandstoneStairs; + mappings[480] = ItemType.MossyStoneBrickStairs; + mappings[481] = ItemType.PolishedDioriteStairs; + mappings[482] = ItemType.MossyCobblestoneStairs; + mappings[483] = ItemType.EndStoneBrickStairs; + mappings[484] = ItemType.StoneStairs; + mappings[485] = ItemType.SmoothSandstoneStairs; + mappings[486] = ItemType.SmoothQuartzStairs; + mappings[487] = ItemType.GraniteStairs; + mappings[488] = ItemType.AndesiteStairs; + mappings[489] = ItemType.RedNetherBrickStairs; + mappings[490] = ItemType.PolishedAndesiteStairs; + mappings[491] = ItemType.DioriteStairs; + mappings[492] = ItemType.PolishedGraniteSlab; + mappings[493] = ItemType.SmoothRedSandstoneSlab; + mappings[494] = ItemType.MossyStoneBrickSlab; + mappings[495] = ItemType.PolishedDioriteSlab; + mappings[496] = ItemType.MossyCobblestoneSlab; + mappings[497] = ItemType.EndStoneBrickSlab; + mappings[498] = ItemType.SmoothSandstoneSlab; + mappings[499] = ItemType.SmoothQuartzSlab; + mappings[500] = ItemType.GraniteSlab; + mappings[501] = ItemType.AndesiteSlab; + mappings[502] = ItemType.RedNetherBrickSlab; + mappings[503] = ItemType.PolishedAndesiteSlab; + mappings[504] = ItemType.DioriteSlab; + mappings[505] = ItemType.Scaffolding; + mappings[506] = ItemType.IronDoor; + mappings[507] = ItemType.OakDoor; + mappings[508] = ItemType.SpruceDoor; + mappings[509] = ItemType.BirchDoor; + mappings[510] = ItemType.JungleDoor; + mappings[511] = ItemType.AcaciaDoor; + mappings[512] = ItemType.DarkOakDoor; + mappings[513] = ItemType.Repeater; + mappings[514] = ItemType.Comparator; + mappings[515] = ItemType.StructureBlock; + mappings[516] = ItemType.Jigsaw; + mappings[517] = ItemType.Composter; + mappings[518] = ItemType.TurtleHelmet; + mappings[519] = ItemType.TurtleScute; + mappings[520] = ItemType.IronShovel; + mappings[521] = ItemType.IronPickaxe; + mappings[522] = ItemType.IronAxe; + mappings[523] = ItemType.FlintAndSteel; + mappings[524] = ItemType.Apple; + mappings[525] = ItemType.Bow; + mappings[526] = ItemType.Arrow; + mappings[527] = ItemType.Coal; + mappings[528] = ItemType.Charcoal; + mappings[529] = ItemType.Diamond; + mappings[530] = ItemType.IronIngot; + mappings[531] = ItemType.GoldIngot; + mappings[532] = ItemType.IronSword; + mappings[533] = ItemType.WoodenSword; + mappings[534] = ItemType.WoodenShovel; + mappings[535] = ItemType.WoodenPickaxe; + mappings[536] = ItemType.WoodenAxe; + mappings[537] = ItemType.StoneSword; + mappings[538] = ItemType.StoneShovel; + mappings[539] = ItemType.StonePickaxe; + mappings[540] = ItemType.StoneAxe; + mappings[541] = ItemType.DiamondSword; + mappings[542] = ItemType.DiamondShovel; + mappings[543] = ItemType.DiamondPickaxe; + mappings[544] = ItemType.DiamondAxe; + mappings[545] = ItemType.Stick; + mappings[546] = ItemType.Bowl; + mappings[547] = ItemType.MushroomStew; + mappings[548] = ItemType.GoldenSword; + mappings[549] = ItemType.GoldenShovel; + mappings[550] = ItemType.GoldenPickaxe; + mappings[551] = ItemType.GoldenAxe; + mappings[552] = ItemType.String; + mappings[553] = ItemType.Feather; + mappings[554] = ItemType.Gunpowder; + mappings[555] = ItemType.WoodenHoe; + mappings[556] = ItemType.StoneHoe; + mappings[557] = ItemType.IronHoe; + mappings[558] = ItemType.DiamondHoe; + mappings[559] = ItemType.GoldenHoe; + mappings[560] = ItemType.WheatSeeds; + mappings[561] = ItemType.Wheat; + mappings[562] = ItemType.Bread; + mappings[563] = ItemType.LeatherHelmet; + mappings[564] = ItemType.LeatherChestplate; + mappings[565] = ItemType.LeatherLeggings; + mappings[566] = ItemType.LeatherBoots; + mappings[567] = ItemType.ChainmailHelmet; + mappings[568] = ItemType.ChainmailChestplate; + mappings[569] = ItemType.ChainmailLeggings; + mappings[570] = ItemType.ChainmailBoots; + mappings[571] = ItemType.IronHelmet; + mappings[572] = ItemType.IronChestplate; + mappings[573] = ItemType.IronLeggings; + mappings[574] = ItemType.IronBoots; + mappings[575] = ItemType.DiamondHelmet; + mappings[576] = ItemType.DiamondChestplate; + mappings[577] = ItemType.DiamondLeggings; + mappings[578] = ItemType.DiamondBoots; + mappings[579] = ItemType.GoldenHelmet; + mappings[580] = ItemType.GoldenChestplate; + mappings[581] = ItemType.GoldenLeggings; + mappings[582] = ItemType.GoldenBoots; + mappings[583] = ItemType.Flint; + mappings[584] = ItemType.Porkchop; + mappings[585] = ItemType.CookedPorkchop; + mappings[586] = ItemType.Painting; + mappings[587] = ItemType.GoldenApple; + mappings[588] = ItemType.EnchantedGoldenApple; + mappings[589] = ItemType.OakSign; + mappings[590] = ItemType.SpruceSign; + mappings[591] = ItemType.BirchSign; + mappings[592] = ItemType.JungleSign; + mappings[593] = ItemType.AcaciaSign; + mappings[594] = ItemType.DarkOakSign; + mappings[595] = ItemType.Bucket; + mappings[596] = ItemType.WaterBucket; + mappings[597] = ItemType.LavaBucket; + mappings[598] = ItemType.Minecart; + mappings[599] = ItemType.Saddle; + mappings[600] = ItemType.Redstone; + mappings[601] = ItemType.Snowball; + mappings[602] = ItemType.OakBoat; + mappings[603] = ItemType.Leather; + mappings[604] = ItemType.MilkBucket; + mappings[605] = ItemType.PufferfishBucket; + mappings[606] = ItemType.SalmonBucket; + mappings[607] = ItemType.CodBucket; + mappings[608] = ItemType.TropicalFishBucket; + mappings[609] = ItemType.Brick; + mappings[610] = ItemType.ClayBall; + mappings[611] = ItemType.SugarCane; + mappings[612] = ItemType.Kelp; + mappings[613] = ItemType.DriedKelpBlock; + mappings[614] = ItemType.Bamboo; + mappings[615] = ItemType.Paper; + mappings[616] = ItemType.Book; + mappings[617] = ItemType.SlimeBall; + mappings[618] = ItemType.ChestMinecart; + mappings[619] = ItemType.FurnaceMinecart; + mappings[620] = ItemType.Egg; + mappings[621] = ItemType.Compass; + mappings[622] = ItemType.FishingRod; + mappings[623] = ItemType.Clock; + mappings[624] = ItemType.GlowstoneDust; + mappings[625] = ItemType.Cod; + mappings[626] = ItemType.Salmon; + mappings[627] = ItemType.TropicalFish; + mappings[628] = ItemType.Pufferfish; + mappings[629] = ItemType.CookedCod; + mappings[630] = ItemType.CookedSalmon; + mappings[631] = ItemType.InkSac; + mappings[632] = ItemType.RedDye; + mappings[633] = ItemType.GreenDye; + mappings[634] = ItemType.CocoaBeans; + mappings[635] = ItemType.LapisLazuli; + mappings[636] = ItemType.PurpleDye; + mappings[637] = ItemType.CyanDye; + mappings[638] = ItemType.LightGrayDye; + mappings[639] = ItemType.GrayDye; + mappings[640] = ItemType.PinkDye; + mappings[641] = ItemType.LimeDye; + mappings[642] = ItemType.YellowDye; + mappings[643] = ItemType.LightBlueDye; + mappings[644] = ItemType.MagentaDye; + mappings[645] = ItemType.OrangeDye; + mappings[646] = ItemType.BoneMeal; + mappings[647] = ItemType.BlueDye; + mappings[648] = ItemType.BrownDye; + mappings[649] = ItemType.BlackDye; + mappings[650] = ItemType.WhiteDye; + mappings[651] = ItemType.Bone; + mappings[652] = ItemType.Sugar; + mappings[653] = ItemType.Cake; + mappings[654] = ItemType.WhiteBed; + mappings[655] = ItemType.OrangeBed; + mappings[656] = ItemType.MagentaBed; + mappings[657] = ItemType.LightBlueBed; + mappings[658] = ItemType.YellowBed; + mappings[659] = ItemType.LimeBed; + mappings[660] = ItemType.PinkBed; + mappings[661] = ItemType.GrayBed; + mappings[662] = ItemType.LightGrayBed; + mappings[663] = ItemType.CyanBed; + mappings[664] = ItemType.PurpleBed; + mappings[665] = ItemType.BlueBed; + mappings[666] = ItemType.BrownBed; + mappings[667] = ItemType.GreenBed; + mappings[668] = ItemType.RedBed; + mappings[669] = ItemType.BlackBed; + mappings[670] = ItemType.Cookie; + mappings[671] = ItemType.FilledMap; + mappings[672] = ItemType.Shears; + mappings[673] = ItemType.MelonSlice; + mappings[674] = ItemType.DriedKelp; + mappings[675] = ItemType.PumpkinSeeds; + mappings[676] = ItemType.MelonSeeds; + mappings[677] = ItemType.Beef; + mappings[678] = ItemType.CookedBeef; + mappings[679] = ItemType.Chicken; + mappings[680] = ItemType.CookedChicken; + mappings[681] = ItemType.RottenFlesh; + mappings[682] = ItemType.EnderPearl; + mappings[683] = ItemType.BlazeRod; + mappings[684] = ItemType.GhastTear; + mappings[685] = ItemType.GoldNugget; + mappings[686] = ItemType.NetherWart; + mappings[687] = ItemType.Potion; + mappings[688] = ItemType.GlassBottle; + mappings[689] = ItemType.SpiderEye; + mappings[690] = ItemType.FermentedSpiderEye; + mappings[691] = ItemType.BlazePowder; + mappings[692] = ItemType.MagmaCream; + mappings[693] = ItemType.BrewingStand; + mappings[694] = ItemType.Cauldron; + mappings[695] = ItemType.EnderEye; + mappings[696] = ItemType.GlisteringMelonSlice; + mappings[697] = ItemType.BatSpawnEgg; + mappings[698] = ItemType.BlazeSpawnEgg; + mappings[699] = ItemType.CatSpawnEgg; + mappings[700] = ItemType.CaveSpiderSpawnEgg; + mappings[701] = ItemType.ChickenSpawnEgg; + mappings[702] = ItemType.CodSpawnEgg; + mappings[703] = ItemType.CowSpawnEgg; + mappings[704] = ItemType.CreeperSpawnEgg; + mappings[705] = ItemType.DolphinSpawnEgg; + mappings[706] = ItemType.DonkeySpawnEgg; + mappings[707] = ItemType.DrownedSpawnEgg; + mappings[708] = ItemType.ElderGuardianSpawnEgg; + mappings[709] = ItemType.EndermanSpawnEgg; + mappings[710] = ItemType.EndermiteSpawnEgg; + mappings[711] = ItemType.EvokerSpawnEgg; + mappings[712] = ItemType.FoxSpawnEgg; + mappings[713] = ItemType.GhastSpawnEgg; + mappings[714] = ItemType.GuardianSpawnEgg; + mappings[715] = ItemType.HorseSpawnEgg; + mappings[716] = ItemType.HuskSpawnEgg; + mappings[717] = ItemType.LlamaSpawnEgg; + mappings[718] = ItemType.MagmaCubeSpawnEgg; + mappings[719] = ItemType.MooshroomSpawnEgg; + mappings[720] = ItemType.MuleSpawnEgg; + mappings[721] = ItemType.OcelotSpawnEgg; + mappings[722] = ItemType.PandaSpawnEgg; + mappings[723] = ItemType.ParrotSpawnEgg; + mappings[724] = ItemType.PhantomSpawnEgg; + mappings[725] = ItemType.PigSpawnEgg; + mappings[726] = ItemType.PillagerSpawnEgg; + mappings[727] = ItemType.PolarBearSpawnEgg; + mappings[728] = ItemType.PufferfishSpawnEgg; + mappings[729] = ItemType.RabbitSpawnEgg; + mappings[730] = ItemType.RavagerSpawnEgg; + mappings[731] = ItemType.SalmonSpawnEgg; + mappings[732] = ItemType.SheepSpawnEgg; + mappings[733] = ItemType.ShulkerSpawnEgg; + mappings[734] = ItemType.SilverfishSpawnEgg; + mappings[735] = ItemType.SkeletonSpawnEgg; + mappings[736] = ItemType.SkeletonHorseSpawnEgg; + mappings[737] = ItemType.SlimeSpawnEgg; + mappings[738] = ItemType.SpiderSpawnEgg; + mappings[739] = ItemType.SquidSpawnEgg; + mappings[740] = ItemType.StraySpawnEgg; + mappings[741] = ItemType.TraderLlamaSpawnEgg; + mappings[742] = ItemType.TropicalFishSpawnEgg; + mappings[743] = ItemType.TurtleSpawnEgg; + mappings[744] = ItemType.VexSpawnEgg; + mappings[745] = ItemType.VillagerSpawnEgg; + mappings[746] = ItemType.VindicatorSpawnEgg; + mappings[747] = ItemType.WanderingTraderSpawnEgg; + mappings[748] = ItemType.WitchSpawnEgg; + mappings[749] = ItemType.WitherSkeletonSpawnEgg; + mappings[750] = ItemType.WolfSpawnEgg; + mappings[751] = ItemType.ZombieSpawnEgg; + mappings[752] = ItemType.ZombieHorseSpawnEgg; + mappings[753] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[754] = ItemType.ZombieVillagerSpawnEgg; + mappings[755] = ItemType.ExperienceBottle; + mappings[756] = ItemType.FireCharge; + mappings[757] = ItemType.WritableBook; + mappings[758] = ItemType.WrittenBook; + mappings[759] = ItemType.Emerald; + mappings[760] = ItemType.ItemFrame; + mappings[761] = ItemType.FlowerPot; + mappings[762] = ItemType.Carrot; + mappings[763] = ItemType.Potato; + mappings[764] = ItemType.BakedPotato; + mappings[765] = ItemType.PoisonousPotato; + mappings[766] = ItemType.Map; + mappings[767] = ItemType.GoldenCarrot; + mappings[768] = ItemType.SkeletonSkull; + mappings[769] = ItemType.WitherSkeletonSkull; + mappings[770] = ItemType.PlayerHead; + mappings[771] = ItemType.ZombieHead; + mappings[772] = ItemType.CreeperHead; + mappings[773] = ItemType.DragonHead; + mappings[774] = ItemType.CarrotOnAStick; + mappings[775] = ItemType.NetherStar; + mappings[776] = ItemType.PumpkinPie; + mappings[777] = ItemType.FireworkRocket; + mappings[778] = ItemType.FireworkStar; + mappings[779] = ItemType.EnchantedBook; + mappings[780] = ItemType.NetherBrick; + mappings[781] = ItemType.Quartz; + mappings[782] = ItemType.TntMinecart; + mappings[783] = ItemType.HopperMinecart; + mappings[784] = ItemType.PrismarineShard; + mappings[785] = ItemType.PrismarineCrystals; + mappings[786] = ItemType.Rabbit; + mappings[787] = ItemType.CookedRabbit; + mappings[788] = ItemType.RabbitStew; + mappings[789] = ItemType.RabbitFoot; + mappings[790] = ItemType.RabbitHide; + mappings[791] = ItemType.ArmorStand; + mappings[792] = ItemType.IronHorseArmor; + mappings[793] = ItemType.GoldenHorseArmor; + mappings[794] = ItemType.DiamondHorseArmor; + mappings[795] = ItemType.LeatherHorseArmor; + mappings[796] = ItemType.Lead; + mappings[797] = ItemType.NameTag; + mappings[798] = ItemType.CommandBlockMinecart; + mappings[799] = ItemType.Mutton; + mappings[800] = ItemType.CookedMutton; + mappings[801] = ItemType.WhiteBanner; + mappings[802] = ItemType.OrangeBanner; + mappings[803] = ItemType.MagentaBanner; + mappings[804] = ItemType.LightBlueBanner; + mappings[805] = ItemType.YellowBanner; + mappings[806] = ItemType.LimeBanner; + mappings[807] = ItemType.PinkBanner; + mappings[808] = ItemType.GrayBanner; + mappings[809] = ItemType.LightGrayBanner; + mappings[810] = ItemType.CyanBanner; + mappings[811] = ItemType.PurpleBanner; + mappings[812] = ItemType.BlueBanner; + mappings[813] = ItemType.BrownBanner; + mappings[814] = ItemType.GreenBanner; + mappings[815] = ItemType.RedBanner; + mappings[816] = ItemType.BlackBanner; + mappings[817] = ItemType.EndCrystal; + mappings[818] = ItemType.ChorusFruit; + mappings[819] = ItemType.PoppedChorusFruit; + mappings[820] = ItemType.Beetroot; + mappings[821] = ItemType.BeetrootSeeds; + mappings[822] = ItemType.BeetrootSoup; + mappings[823] = ItemType.DragonBreath; + mappings[824] = ItemType.SplashPotion; + mappings[825] = ItemType.SpectralArrow; + mappings[826] = ItemType.TippedArrow; + mappings[827] = ItemType.LingeringPotion; + mappings[828] = ItemType.Shield; + mappings[829] = ItemType.Elytra; + mappings[830] = ItemType.SpruceBoat; + mappings[831] = ItemType.BirchBoat; + mappings[832] = ItemType.JungleBoat; + mappings[833] = ItemType.AcaciaBoat; + mappings[834] = ItemType.DarkOakBoat; + mappings[835] = ItemType.TotemOfUndying; + mappings[836] = ItemType.ShulkerShell; + mappings[837] = ItemType.IronNugget; + mappings[838] = ItemType.KnowledgeBook; + mappings[839] = ItemType.DebugStick; + mappings[840] = ItemType.MusicDisc13; + mappings[841] = ItemType.MusicDiscCat; + mappings[842] = ItemType.MusicDiscBlocks; + mappings[843] = ItemType.MusicDiscChirp; + mappings[844] = ItemType.MusicDiscFar; + mappings[845] = ItemType.MusicDiscMall; + mappings[846] = ItemType.MusicDiscMellohi; + mappings[847] = ItemType.MusicDiscStal; + mappings[848] = ItemType.MusicDiscStrad; + mappings[849] = ItemType.MusicDiscWard; + mappings[850] = ItemType.MusicDisc11; + mappings[851] = ItemType.MusicDiscWait; + mappings[852] = ItemType.Trident; + mappings[853] = ItemType.PhantomMembrane; + mappings[854] = ItemType.NautilusShell; + mappings[855] = ItemType.HeartOfTheSea; + mappings[856] = ItemType.Crossbow; + mappings[857] = ItemType.SuspiciousStew; + mappings[858] = ItemType.Loom; + mappings[859] = ItemType.FlowerBannerPattern; + mappings[860] = ItemType.CreeperBannerPattern; + mappings[861] = ItemType.SkullBannerPattern; + mappings[862] = ItemType.MojangBannerPattern; + mappings[863] = ItemType.GlobeBannerPattern; + mappings[864] = ItemType.Barrel; + mappings[865] = ItemType.Smoker; + mappings[866] = ItemType.BlastFurnace; + mappings[867] = ItemType.CartographyTable; + mappings[868] = ItemType.FletchingTable; + mappings[869] = ItemType.Grindstone; + mappings[870] = ItemType.Lectern; + mappings[871] = ItemType.SmithingTable; + mappings[872] = ItemType.Stonecutter; + mappings[873] = ItemType.Bell; + mappings[874] = ItemType.Lantern; + mappings[875] = ItemType.SweetBerries; + mappings[876] = ItemType.Campfire; + } protected override Dictionary<int, ItemType> GetDict() { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 8a7dbd67..8251f779 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3925,9 +3925,9 @@ namespace MinecraftClient.Protocol.Handlers private bool SkipRecipeBookSettings(Queue<byte> packetData) { - // MC 1.13 uses 4 booleans for the crafting/smelting recipe book states. - // MC 1.14+ expands this to 8 booleans by adding blast furnace and smoker states. - int boolCount = protocolVersion >= MC_1_14_Version ? 8 : 4; + // MC 1.13-1.16.1 uses 4 booleans for the crafting/smelting recipe book states. + // MC 1.16.2+ expands this to 8 booleans through RecipeBookSettings. + int boolCount = protocolVersion >= MC_1_16_2_Version ? 8 : 4; if (packetData.Count < boolCount) return false; From 12ab759f3b6d96742ff1370a8f8149307a195ecb Mon Sep 17 00:00:00 2001 From: Anon <bgteam@live.com> Date: Sun, 3 May 2026 20:12:52 +0200 Subject: [PATCH 4/4] Fix TUI book controls Polish TUI book navigation and signed-book handling, update localized shortcut text, and document the final PageUp/PageDown interaction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- MinecraftClient/Commands/Book.cs | 23 ++- .../Translations/Translations.Designer.cs | 16 ++ .../Resources/Translations/Translations.resx | 12 ++ MinecraftClient/Tui/BookTuiHost.cs | 145 +++++++++++++++--- docs/guide/usage.md | 2 + 5 files changed, 168 insertions(+), 30 deletions(-) diff --git a/MinecraftClient/Commands/Book.cs b/MinecraftClient/Commands/Book.cs index 1362d227..e035f277 100644 --- a/MinecraftClient/Commands/Book.cs +++ b/MinecraftClient/Commands/Book.cs @@ -93,7 +93,7 @@ namespace MinecraftClient.Commands private int OpenEditor(CmdResult r) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out _)) + if (!EnsureWritable(r, handler, out _, Translations.cmd_book_cannot_edit_signed)) return -1; return BookTuiHost.TryOpen(handler, BookHand.Main, editable: true) @@ -104,7 +104,7 @@ namespace MinecraftClient.Commands private int WriteBook(CmdResult r, string text) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out _)) + if (!EnsureWritable(r, handler, out _, Translations.cmd_book_cannot_edit_signed)) return -1; IReadOnlyList<string> pages = SplitPages(text); @@ -127,7 +127,7 @@ namespace MinecraftClient.Commands private int EditPage(CmdResult r, int page, string text) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out BookContent content)) + if (!EnsureWritable(r, handler, out BookContent content, Translations.cmd_book_cannot_edit_signed)) return -1; List<string> pages = content.Pages.ToList(); @@ -146,7 +146,7 @@ namespace MinecraftClient.Commands private int InsertPage(CmdResult r, int page, string text) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out BookContent content)) + if (!EnsureWritable(r, handler, out BookContent content, Translations.cmd_book_cannot_edit_signed)) return -1; List<string> pages = content.Pages.ToList(); @@ -165,7 +165,7 @@ namespace MinecraftClient.Commands private int DeletePage(CmdResult r, int page) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out BookContent content)) + if (!EnsureWritable(r, handler, out BookContent content, Translations.cmd_book_cannot_edit_signed)) return -1; List<string> pages = content.Pages.ToList(); @@ -187,7 +187,7 @@ namespace MinecraftClient.Commands private int SignBook(CmdResult r, string title) { McClient handler = CmdResult.currentHandler!; - if (!EnsureWritable(r, handler, out BookContent content)) + if (!EnsureWritable(r, handler, out BookContent content, Translations.cmd_book_already_signed)) return -1; string normalizedTitle = title.Trim(); @@ -208,7 +208,7 @@ namespace MinecraftClient.Commands return false; } - private static bool EnsureWritable(CmdResult r, McClient handler, out BookContent content) + private static bool EnsureWritable(CmdResult r, McClient handler, out BookContent content, string signedBookMessage) { content = BookContent.EmptyWritable; if (!EnsureInventory(r, handler)) @@ -217,13 +217,20 @@ namespace MinecraftClient.Commands Item? item = handler.GetHeldBook(); if (!BookContentHelper.IsWritableBook(item)) { - r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_book_not_holding_writable); + r.SetAndReturn(CmdResult.Status.Fail, GetWritableBookFailureMessage(item, signedBookMessage)); return false; } return BookContentHelper.TryRead(item, out content); } + private static string GetWritableBookFailureMessage(Item? item, string signedBookMessage) + { + return BookContentHelper.TryRead(item, out BookContent content) && content.IsSigned + ? signedBookMessage + : Translations.cmd_book_not_holding_writable; + } + private static IReadOnlyList<string> SplitPages(string text) { return BookContentHelper.NormalizePages(DecodeInlineText(text).Split(PageDelimiter)); diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index bccd0a57..dc76b6c4 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -7584,6 +7584,14 @@ namespace MinecraftClient { get { return ResourceManager.GetString("cmd.book.not_holding_writable", resourceCulture); } } + internal static string cmd_book_already_signed { + get { return ResourceManager.GetString("cmd.book.already_signed", resourceCulture); } + } + + internal static string cmd_book_cannot_edit_signed { + get { return ResourceManager.GetString("cmd.book.cannot_edit_signed", resourceCulture); } + } + internal static string cmd_book_tui_opened { get { return ResourceManager.GetString("cmd.book.tui_opened", resourceCulture); } } @@ -7696,5 +7704,13 @@ namespace MinecraftClient { get { return ResourceManager.GetString("tui.book.reading", resourceCulture); } } + internal static string tui_book_edit_shortcut_tip { + get { return ResourceManager.GetString("tui.book.edit_shortcut_tip", resourceCulture); } + } + + internal static string tui_book_page_shortcut_tip { + get { return ResourceManager.GetString("tui.book.page_shortcut_tip", resourceCulture); } + } + } } diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index aa167797..9d60b82d 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2683,6 +2683,12 @@ see item details.</value> <data name="cmd.book.not_holding_writable" xml:space="preserve"> <value>You must hold a writable book in your main hand.</value> </data> + <data name="cmd.book.already_signed" xml:space="preserve"> + <value>Book already signed.</value> + </data> + <data name="cmd.book.cannot_edit_signed" xml:space="preserve"> + <value>You cannot edit a signed book.</value> + </data> <data name="cmd.book.tui_opened" xml:space="preserve"> <value>Book TUI opened.</value> </data> @@ -2767,4 +2773,10 @@ see item details.</value> <data name="tui.book.reading" xml:space="preserve"> <value>Reading book.</value> </data> + <data name="tui.book.edit_shortcut_tip" xml:space="preserve"> + <value>PageUp/PageDown: previous/next page</value> + </data> + <data name="tui.book.page_shortcut_tip" xml:space="preserve"> + <value>PageUp/PageDown: previous/next page</value> + </data> </root> diff --git a/MinecraftClient/Tui/BookTuiHost.cs b/MinecraftClient/Tui/BookTuiHost.cs index eac8c2b0..5d20b13f 100644 --- a/MinecraftClient/Tui/BookTuiHost.cs +++ b/MinecraftClient/Tui/BookTuiHost.cs @@ -4,6 +4,7 @@ using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.Input; +using Avalonia.Interactivity; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Threading; @@ -58,14 +59,23 @@ internal sealed class BookView : UserControl private readonly List<string> pages; private readonly TextBlock header; private readonly TextBlock status; + private readonly TextBlock shortcutTip; private readonly TextBox pageText; private readonly TextBox titleText; + private readonly Button previousButton; + private readonly Button nextButton; + private readonly Button insertButton; + private readonly Button deleteButton; + private readonly Button saveButton; + private readonly Button signButton; + private bool bookSigned; private int pageIndex; public BookView(McClient handler, BookContent content, bool editable) { this.handler = handler; this.editable = editable; + bookSigned = content.IsSigned; pages = content.Pages.ToList(); if (pages.Count == 0) pages.Add(string.Empty); @@ -87,11 +97,19 @@ internal sealed class BookView : UserControl TextWrapping = TextWrapping.Wrap }; + shortcutTip = new TextBlock + { + Foreground = Brushes.DarkGray, + Margin = new Thickness(1, 0), + Text = Translations.tui_book_page_shortcut_tip, + TextWrapping = TextWrapping.Wrap + }; + pageText = new TextBox { AcceptsReturn = true, TextWrapping = TextWrapping.Wrap, - IsReadOnly = !editable, + IsReadOnly = !CanEdit, Foreground = Brushes.White, Background = Brushes.Black, BorderBrush = Brushes.Gray, @@ -100,20 +118,27 @@ internal sealed class BookView : UserControl }; pageText.TextChanged += (_, _) => { - if (editable && pageIndex >= 0 && pageIndex < pages.Count) + if (CanEdit && pageIndex >= 0 && pageIndex < pages.Count) pages[pageIndex] = pageText.Text ?? string.Empty; }; titleText = new TextBox { Watermark = Translations.tui_book_title_watermark, - IsVisible = editable, + IsVisible = CanEdit, Foreground = Brushes.White, Background = Brushes.Black, BorderBrush = Brushes.Gray, Margin = new Thickness(1) }; + previousButton = Button(Translations.tui_book_prev, (_, _) => TryMovePage(-1)); + nextButton = Button(Translations.tui_book_next, (_, _) => TryMovePage(1)); + insertButton = Button(Translations.tui_book_insert, (_, _) => InsertPage(), editable); + deleteButton = Button(Translations.tui_book_delete, (_, _) => DeletePage(), editable); + saveButton = Button(Translations.tui_book_save, (_, _) => Save(), editable); + signButton = Button(Translations.tui_book_sign, (_, _) => Sign(), editable); + var controls = new StackPanel { Orientation = Orientation.Horizontal, @@ -121,12 +146,12 @@ internal sealed class BookView : UserControl Margin = new Thickness(1), Children = { - Button(Translations.tui_book_prev, (_, _) => MovePage(-1)), - Button(Translations.tui_book_next, (_, _) => MovePage(1)), - Button(Translations.tui_book_insert, (_, _) => InsertPage(), editable), - Button(Translations.tui_book_delete, (_, _) => DeletePage(), editable), - Button(Translations.tui_book_save, (_, _) => Save(), editable), - Button(Translations.tui_book_sign, (_, _) => Sign(), editable), + previousButton, + nextButton, + insertButton, + deleteButton, + saveButton, + signButton, Button(Translations.tui_book_close, (_, _) => Close()) } }; @@ -138,6 +163,7 @@ internal sealed class BookView : UserControl { DockTo(header, Dock.Top), DockTo(status, Dock.Bottom), + DockTo(shortcutTip, Dock.Bottom), DockTo(controls, Dock.Bottom), DockTo(titleText, Dock.Bottom), pageText @@ -145,26 +171,31 @@ internal sealed class BookView : UserControl }; Content = panel; + AttachedToVisualTree += (_, _) => + { + AddHandler(KeyDownEvent, OnTunnelKeyDown, RoutingStrategies.Tunnel, handledEventsToo: true); + FocusPageText(); + }; + DetachedFromVisualTree += (_, _) => RemoveHandler(KeyDownEvent, OnTunnelKeyDown); Refresh(); } - protected override void OnKeyDown(KeyEventArgs e) + private bool CanEdit => editable && !bookSigned; + + private void OnTunnelKeyDown(object? sender, KeyEventArgs e) { if (e.Key == Key.PageUp) { - MovePage(-1); + TryMovePage(-1); e.Handled = true; return; } if (e.Key == Key.PageDown) { - MovePage(1); + TryMovePage(1); e.Handled = true; - return; } - - base.OnKeyDown(e); } private static Control DockTo(Control control, Dock dock) @@ -186,14 +217,22 @@ internal sealed class BookView : UserControl return button; } - private void MovePage(int delta) + private bool TryMovePage(int delta) { - pageIndex = Math.Clamp(pageIndex + delta, 0, pages.Count - 1); + int targetPageIndex = Math.Clamp(pageIndex + delta, 0, pages.Count - 1); + if (targetPageIndex == pageIndex) + return false; + + pageIndex = targetPageIndex; Refresh(); + return true; } private void InsertPage() { + if (!CanEdit) + return; + pages.Insert(pageIndex + 1, string.Empty); pageIndex++; Refresh(); @@ -201,6 +240,9 @@ internal sealed class BookView : UserControl private void DeletePage() { + if (!CanEdit) + return; + if (pages.Count == 1) pages[0] = string.Empty; else @@ -213,6 +255,14 @@ internal sealed class BookView : UserControl private void Save() { + if (bookSigned || IsHeldBookSigned()) + { + bookSigned = true; + status.Text = Translations.cmd_book_cannot_edit_signed; + RefreshEditability(); + return; + } + if (!Validate(out string error)) { status.Text = error; @@ -226,6 +276,14 @@ internal sealed class BookView : UserControl private void Sign() { + if (bookSigned || IsHeldBookSigned()) + { + bookSigned = true; + status.Text = Translations.cmd_book_already_signed; + RefreshEditability(); + return; + } + string title = (titleText.Text ?? string.Empty).Trim(); if (!Validate(out string error, title)) { @@ -233,8 +291,16 @@ internal sealed class BookView : UserControl return; } - status.Text = handler.SendBookEdit(pages, title) - ? Translations.tui_book_signed + if (handler.SendBookEdit(pages, title)) + { + bookSigned = true; + status.Text = Translations.tui_book_signed; + RefreshEditability(); + return; + } + + status.Text = IsHeldBookSigned() + ? Translations.cmd_book_already_signed : Translations.tui_book_save_failed; } @@ -274,9 +340,44 @@ internal sealed class BookView : UserControl private void Refresh() { - pageText.Text = pages[pageIndex]; + string currentPageText = pages[pageIndex]; + if (!string.Equals(pageText.Text, currentPageText, StringComparison.Ordinal)) + pageText.Text = currentPageText; + header.Text = string.Format(Translations.tui_book_page_header, pageIndex + 1, pages.Count); - status.Text = editable ? Translations.tui_book_editing : Translations.tui_book_reading; - pageText.Focus(); + status.Text = CanEdit ? Translations.tui_book_editing : Translations.tui_book_reading; + RefreshEditability(); + FocusPageText(); + } + + private void RefreshEditability() + { + previousButton.IsEnabled = pageIndex > 0; + nextButton.IsEnabled = pageIndex < pages.Count - 1; + insertButton.IsEnabled = CanEdit; + deleteButton.IsEnabled = CanEdit; + saveButton.IsEnabled = CanEdit; + signButton.IsEnabled = CanEdit; + pageText.IsReadOnly = !CanEdit; + titleText.IsEnabled = CanEdit; + titleText.IsVisible = CanEdit; + shortcutTip.Text = CanEdit + ? Translations.tui_book_edit_shortcut_tip + : Translations.tui_book_page_shortcut_tip; + } + + private void FocusPageText() + { + Dispatcher.UIThread.Post(() => + { + pageText.Focus(); + if (CanEdit) + pageText.CaretIndex = pageText.Text?.Length ?? 0; + }, DispatcherPriority.Input); + } + + private bool IsHeldBookSigned() + { + return BookContentHelper.TryRead(handler.GetHeldBook(BookHand.Main), out BookContent content) && content.IsSigned; } } diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 6aa10b6a..1cc65d87 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -326,6 +326,8 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q The interactive editor is only available in TUI mode. + In the TUI book view, `PageUp`/`PageDown` switches pages. + - **Examples:** Read the held book: