From 083f401ee5a9c794d445431f96c83cef26295392 Mon Sep 17 00:00:00 2001 From: Myles Date: Sun, 28 Oct 2018 16:30:26 +0000 Subject: [PATCH 01/24] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 26 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 +++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..ec0895c61 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Create a bug report so we can fix it + +--- + +**Describe the bug, provide any errors** +A clear and concise description of what the bug is. Can you http://hastebin the error? + +**How can we reproduce it?** +Steps to reproduce the behavior: +1. Login on 1.12' +2. Click on '....' +3. The '....' is displayed wrong + +**Expected behaviour** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**ViaVersion Dump:** +- Type /viaversion dump, and put the link here. + +**Additional server info** +Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins? diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..8bbc2c4fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for ViaVersion + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Which versions is this for?** +Does the feature apply to any specific versions? If so put them here. From 2c18adf202060f23bb30f0320a1b2b1e55870a61 Mon Sep 17 00:00:00 2001 From: Myles Date: Sun, 28 Oct 2018 16:38:08 +0000 Subject: [PATCH 02/24] Delete ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 80bbbc13c..000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -### What is the output link of /viaversion dump? - - -### Are you using any additional software like BungeeCord? If so, what software and version? (Please list your plugins as well) - - -### How does this error happen? login? Using an item? - - -### Is there an error in the console? Use pastebin.com. Is there a kick message? - From 78aefa936f4561985e7167542f0d4f592f71f524 Mon Sep 17 00:00:00 2001 From: Myles Date: Sun, 28 Oct 2018 16:38:53 +0000 Subject: [PATCH 03/24] Minor bug report typo --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ec0895c61..b0e07f6e3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -5,7 +5,7 @@ about: Create a bug report so we can fix it --- **Describe the bug, provide any errors** -A clear and concise description of what the bug is. Can you http://hastebin the error? +A clear and concise description of what the bug is. Can you https://hastebin.com the error? **How can we reproduce it?** Steps to reproduce the behavior: From b7606aece04c34aead742889b4400cc4b7e7b491 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Wed, 31 Oct 2018 16:26:55 -0300 Subject: [PATCH 04/24] Tolerate some identifiers. Should fix #1063 --- .../protocol1_13to1_12_2/packets/InventoryPackets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java index fce53597a..3ba30ba7b 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java @@ -447,7 +447,7 @@ public class InventoryPackets { case "WDL|REQUEST": return "wdl:request"; default: - return old.matches("[0-9a-z_-]+:[0-9a-z_/.-]+") // Identifier regex + return old.matches("([0-9a-z_-]*:)?[0-9a-z_/.-]*") // Identifier regex ? old : "viaversion:legacy/" + BaseEncoding.base32().lowerCase().withPadChar('-').encode( old.getBytes(StandardCharsets.UTF_8)); From e6922eae4677139e4c3c7dce7d931edb6259c915 Mon Sep 17 00:00:00 2001 From: Myles Date: Thu, 1 Nov 2018 22:41:56 +0000 Subject: [PATCH 05/24] Don't use -1 if provided by ProtocolDetectorService on Bungee #1064 --- .../service/ProtocolDetectorService.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java index e3aa9defe..252959224 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java @@ -58,19 +58,22 @@ public class ProtocolDetectorService implements Runnable { @Override public void done(ServerPing serverPing, Throwable throwable) { if (throwable == null && serverPing != null && serverPing.getVersion() != null) { - detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); - if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) { - Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); - Integer protocol = servers.get(key); - if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { - return; + // Ensure protocol is positive, some services will return -1 + if (serverPing.getVersion().getProtocol() > 0) { + detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); + if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) { + Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); + Integer protocol = servers.get(key); + if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { + return; + } + // Ensure we're the only ones writing to the config + synchronized (Via.getPlatform().getConfigurationProvider()) { + servers.put(key, serverPing.getVersion().getProtocol()); + } + // Save + Via.getPlatform().getConfigurationProvider().saveConfig(); } - // Ensure we're the only ones writing to the config - synchronized (Via.getPlatform().getConfigurationProvider()) { - servers.put(key, serverPing.getVersion().getProtocol()); - } - // Save - Via.getPlatform().getConfigurationProvider().saveConfig(); } } } From 437b02c961737af7dafc7af2f5e63db2b31bcd96 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sun, 4 Nov 2018 08:56:22 -0200 Subject: [PATCH 06/24] color rewriting changes --- .../Protocol1_13To1_12_2.java | 139 +++++++++--------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index f775508d5..2c2adfd9f 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -47,79 +47,79 @@ public class Protocol1_13To1_12_2 extends Protocol { } }; - public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS = new PacketHandler() { // *insert here a good name* - @Override - public void handle(PacketWrapper w) throws Exception { - // Send fake declare commands - w.create(0x11, new ValueCreator() { + public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS = + new PacketHandler() { // *insert here a good name* @Override - public void write(PacketWrapper wrapper) { - wrapper.write(Type.VAR_INT, 2); // Size - // Write root node - wrapper.write(Type.VAR_INT, 0); // Mark as command - wrapper.write(Type.VAR_INT, 1); // 1 child - wrapper.write(Type.VAR_INT, 1); // Child is at 1 + public void handle(PacketWrapper w) throws Exception { + // Send fake declare commands + w.create(0x11, new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) { + wrapper.write(Type.VAR_INT, 2); // Size + // Write root node + wrapper.write(Type.VAR_INT, 0); // Mark as command + wrapper.write(Type.VAR_INT, 1); // 1 child + wrapper.write(Type.VAR_INT, 1); // Child is at 1 - // Write arg node - wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command - wrapper.write(Type.VAR_INT, 0); // No children - // Extra data - wrapper.write(Type.STRING, "args"); // Arg name - wrapper.write(Type.STRING, "brigadier:string"); - wrapper.write(Type.VAR_INT, 2); // Greedy - wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server + // Write arg node + wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command + wrapper.write(Type.VAR_INT, 0); // No children + // Extra data + wrapper.write(Type.STRING, "args"); // Arg name + wrapper.write(Type.STRING, "brigadier:string"); + wrapper.write(Type.VAR_INT, 2); // Greedy + wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server - wrapper.write(Type.VAR_INT, 0); // Root node index + wrapper.write(Type.VAR_INT, 0); // Root node index + } + }).send(Protocol1_13To1_12_2.class); + + // Send tags packet + w.create(0x55, new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags + for (Map.Entry tag : MappingData.blockTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags + for (Map.Entry tag : MappingData.itemTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags + for (Map.Entry tag : MappingData.fluidTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + } + }).send(Protocol1_13To1_12_2.class); } - }).send(Protocol1_13To1_12_2.class); - - // Send tags packet - w.create(0x55, new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags - for (Map.Entry tag : MappingData.blockTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags - for (Map.Entry tag : MappingData.itemTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags - for (Map.Entry tag : MappingData.fluidTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - } - }).send(Protocol1_13To1_12_2.class); - } - }; + }; // @formatter:off // These are arbitrary rewrite values, it just needs an invalid color code character. - protected static EnumMap SCOREBOARD_TEAM_NAME_REWRITE = new EnumMap(ChatColor.class) {{ - put(ChatColor.BLACK, ChatColor.COLOR_CHAR + "g"); - put(ChatColor.DARK_BLUE, ChatColor.COLOR_CHAR + "h"); - put(ChatColor.DARK_GREEN, ChatColor.COLOR_CHAR + "i"); - put(ChatColor.DARK_AQUA, ChatColor.COLOR_CHAR + "j"); - put(ChatColor.DARK_RED, ChatColor.COLOR_CHAR + "p"); - put(ChatColor.DARK_PURPLE, ChatColor.COLOR_CHAR + "q"); - put(ChatColor.GOLD, ChatColor.COLOR_CHAR + "s"); - put(ChatColor.GRAY, ChatColor.COLOR_CHAR + "t"); - put(ChatColor.DARK_GRAY, ChatColor.COLOR_CHAR + "u"); - put(ChatColor.BLUE, ChatColor.COLOR_CHAR + "v"); - put(ChatColor.GREEN, ChatColor.COLOR_CHAR + "w"); - put(ChatColor.AQUA, ChatColor.COLOR_CHAR + "x"); - put(ChatColor.RED, ChatColor.COLOR_CHAR + "y"); - put(ChatColor.LIGHT_PURPLE, ChatColor.COLOR_CHAR + "z"); - put(ChatColor.YELLOW, ChatColor.COLOR_CHAR + "!"); - put(ChatColor.WHITE, ChatColor.COLOR_CHAR + "?"); - }}; + protected static EnumMap SCOREBOARD_TEAM_NAME_REWRITE = new EnumMap<>(ChatColor.class); // @formatter:on static { + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.BLACK, 'g'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_BLUE, 'h'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_GREEN, 'i'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_AQUA, 'j'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_RED, 'p'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_PURPLE, 'q'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GOLD, 's'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GRAY, 't'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_GRAY, 'u'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.BLUE, 'v'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GREEN, 'w'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.AQUA, 'x'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.RED, 'y'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.LIGHT_PURPLE, 'z'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.YELLOW, '!'); + SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.WHITE, '?'); MappingData.init(); } @@ -933,14 +933,13 @@ public class Protocol1_13To1_12_2 extends Protocol { // will just send colour as 'invisible' character if (ChatColor.stripColor(name).length() == 0) { StringBuilder newName = new StringBuilder(); - for (int i = 0; i < name.length() / 2; i++) { - ChatColor color = ChatColor.getByChar(name.charAt(i * 2 + 1)); - String rewrite = SCOREBOARD_TEAM_NAME_REWRITE.get(color); - if (rewrite != null) { // just in case, should never happen - newName.append(rewrite); - } else { - newName.append(name); + for (int i = 1; i < name.length(); i += 2) { + char colorChar = name.charAt(i); + Character rewrite = SCOREBOARD_TEAM_NAME_REWRITE.get(ChatColor.getByChar(colorChar)); + if (rewrite == null) { + rewrite = colorChar; } + newName.append('§').append(rewrite); } name = newName.toString(); } From bec27e0fa68f9ea178d44feaedc6b416d69c855f Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sun, 4 Nov 2018 10:51:29 -0200 Subject: [PATCH 07/24] Use ChatColor.COLOR_CHAR --- .../protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index 2c2adfd9f..de7d4e8c0 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -939,7 +939,7 @@ public class Protocol1_13To1_12_2 extends Protocol { if (rewrite == null) { rewrite = colorChar; } - newName.append('§').append(rewrite); + newName.append(ChatColor.COLOR_CHAR).append(rewrite); } name = newName.toString(); } From d9eff7bb5cab02e4c7953bd256c57924d14115a5 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Thu, 8 Nov 2018 16:10:45 -0200 Subject: [PATCH 08/24] Translation rewriting --- .../protocol1_13to1_12_2/ChatRewriter.java | 37 + .../Protocol1_13To1_12_2.java | 129 +- .../data/MappingData.java | 30 + .../data/mapping-lang-1.12-1.13.json | 1679 +++++++++++++++++ 4 files changed, 1867 insertions(+), 8 deletions(-) create mode 100644 common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java index 047cecac6..e5081c2e4 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java @@ -4,7 +4,9 @@ import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; import net.md_5.bungee.chat.ComponentSerializer; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; import java.util.ArrayList; import java.util.regex.Matcher; @@ -115,4 +117,39 @@ public class ChatRewriter { public static String jsonTextToLegacy(String value) { return TextComponent.toLegacyText(ComponentSerializer.parse(value)); } + + public static String processTranslate(String value) { + BaseComponent[] components = ComponentSerializer.parse(value); + for (BaseComponent component : components) { + processTranslate(component); + } + if (components.length == 1) { + return ComponentSerializer.toString(components[0]); + } else { + return ComponentSerializer.toString(components); + } + } + + private static void processTranslate(BaseComponent component) { + if (component instanceof TranslatableComponent) { + String oldTranslate = ((TranslatableComponent) component).getTranslate(); + String newTranslate; + newTranslate = MappingData.translateMapping.get(oldTranslate); + if (newTranslate == null) MappingData.mojangTranslation.get(oldTranslate); + if (newTranslate != null) { + ((TranslatableComponent) component).setTranslate(newTranslate); + } + for (BaseComponent baseComponent : ((TranslatableComponent) component).getWith()) { + processTranslate(baseComponent); + } + } + if (component.getHoverEvent() != null) { + for (BaseComponent baseComponent : component.getHoverEvent().getValue()) { + processTranslate(baseComponent); + } + } + for (BaseComponent baseComponent : component.getExtra()) { + processTranslate(baseComponent); + } + } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index de7d4e8c0..ceda16785 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -132,6 +132,19 @@ public class Protocol1_13To1_12_2 extends Protocol { // Outgoing packets + registerOutgoing(State.LOGIN, 0x0, 0x0, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0))); + } + }); + } + }); + registerOutgoing(State.STATUS, 0x00, 0x00, new PacketRemapper() { @Override public void registerMap() { @@ -171,7 +184,36 @@ public class Protocol1_13To1_12_2 extends Protocol { } }); - registerOutgoing(State.PLAY, 0xF, 0xE); + // Boss bar + registerOutgoing(State.PLAY, 0xC, 0xC, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UUID); + map(Type.VAR_INT); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int action = wrapper.get(Type.VAR_INT, 0); + if (action == 0 || action == 3) { + wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); + } + } + }); + } + }); + // Chat message + registerOutgoing(State.PLAY, 0xF, 0xE, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0))); + } + }); + } + }); // WorldPackets 0x10 -> 0x0F // Tab-Complete @@ -219,13 +261,39 @@ public class Protocol1_13To1_12_2 extends Protocol { // New packet 0x11, declare commands registerOutgoing(State.PLAY, 0x11, 0x12); registerOutgoing(State.PLAY, 0x12, 0x13); - registerOutgoing(State.PLAY, 0x13, 0x14); + // Open window + registerOutgoing(State.PLAY, 0x13, 0x14, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // Id + map(Type.STRING); // Window type + map(Type.STRING); // Title + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.STRING, 1, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 1))); + } + }); + } + }); // InventoryPackets 0x14 -> 0x15 // InventoryPackets 0x15 -> 0x16 // InventoryPackets 0x16 -> 0x17 registerOutgoing(State.PLAY, 0x17, 0x18); // WorldPackets 0x18 -> 0x19 - registerOutgoing(State.PLAY, 0x1A, 0x1B); + // Disconnect + registerOutgoing(State.PLAY, 0x1A, 0x1B, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0))); + } + }); + } + }); registerOutgoing(State.PLAY, 0x1B, 0x1C); // New packet 0x1D - NBT Query registerOutgoing(State.PLAY, 0x1C, 0x1E); @@ -328,7 +396,23 @@ public class Protocol1_13To1_12_2 extends Protocol { } }); registerOutgoing(State.PLAY, 0x2C, 0x2E); - registerOutgoing(State.PLAY, 0x2D, 0x2F); + // Combat event + registerOutgoing(State.PLAY, 0x2D, 0x2F, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // Event + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (wrapper.get(Type.VAR_INT, 0) == 2) { // Entity dead + wrapper.passthrough(Type.VAR_INT); // Player id + wrapper.passthrough(Type.INT); // Entity id + wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); + } + } + }); + } + }); registerOutgoing(State.PLAY, 0x2E, 0x30); // New 0x31 - Face Player registerOutgoing(State.PLAY, 0x2F, 0x32); @@ -482,7 +566,22 @@ public class Protocol1_13To1_12_2 extends Protocol { }); registerOutgoing(State.PLAY, 0x46, 0x49); registerOutgoing(State.PLAY, 0x47, 0x4A); - registerOutgoing(State.PLAY, 0x48, 0x4B); + // Title + registerOutgoing(State.PLAY, 0x48, 0x4B, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // Action + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int action = wrapper.get(Type.VAR_INT, 0); + if (action >= 0 && action <= 2) { + wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); + } + } + }); + } + }); // New 0x4C - Stop Sound // Sound Effect packet @@ -500,7 +599,21 @@ public class Protocol1_13To1_12_2 extends Protocol { }); } }); - registerOutgoing(State.PLAY, 0x4A, 0x4E); + // Player list header and footer + registerOutgoing(State.PLAY, 0x4A, 0x4E, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); + map(Type.STRING); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0))); + wrapper.set(Type.STRING, 1, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 1))); + } + }); + } + }); registerOutgoing(State.PLAY, 0x4B, 0x4F); registerOutgoing(State.PLAY, 0x4C, 0x50); // Advancements @@ -522,8 +635,8 @@ public class Protocol1_13To1_12_2 extends Protocol { // Display data if (wrapper.passthrough(Type.BOOLEAN)) { - wrapper.passthrough(Type.STRING); // Title - wrapper.passthrough(Type.STRING); // Description + wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); // Title + wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); // Description Item icon = wrapper.read(Type.ITEM); InventoryPackets.toClient(icon); wrapper.write(Type.FLAT_ITEM, icon); // Translate item to flat item diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java index e73f18c09..4ec3c9776 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java @@ -2,15 +2,19 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import com.google.common.io.CharStreams; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.util.GsonUtil; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -21,6 +25,8 @@ public class MappingData { public static Map itemTags = new HashMap<>(); public static Map fluidTags = new HashMap<>(); public static BiMap oldEnchantmentsIds = HashBiMap.create(); + public static Map translateMapping = new HashMap<>(); + public static Map mojangTranslation = new HashMap<>(); public static EnchantmentMappings enchantmentMappings; public static SoundMappings soundMappings; public static BlockMappings blockMappings; @@ -42,6 +48,30 @@ public class MappingData { enchantmentMappings = new EnchantmentMappingByteArray(mapping1_12.getAsJsonObject("enchantments"), mapping1_13.getAsJsonObject("enchantments")); Via.getPlatform().getLogger().info("Loading sound mapping..."); soundMappings = new SoundMappingShortArray(mapping1_12.getAsJsonArray("sounds"), mapping1_13.getAsJsonArray("sounds")); + Via.getPlatform().getLogger().info("Loading translation mappping"); + translateMapping = GsonUtil.getGson().fromJson( + new InputStreamReader( + MappingData.class.getClassLoader() + .getResourceAsStream("assets/viaversion/data/mapping-lang-1.12-1.13.json") + ), + (new TypeToken>(){}).getType()); + try { + String[] lines; + try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader() + .getResourceAsStream("mojang-translations/en_US.properties"), StandardCharsets.UTF_8)) { + lines = CharStreams.toString(reader).split("\n"); + } + for (String line : lines) { + if (line.isEmpty()) continue; + String[] keyAndTranslation = line.split("=", 2); + if (keyAndTranslation.length != 2) continue; + if (!translateMapping.containsKey(keyAndTranslation[0])) { + translateMapping.put(keyAndTranslation[0], keyAndTranslation[1]); + } + } + } catch (IOException e) { + e.printStackTrace(); + } } public static JsonObject loadData(String name) { diff --git a/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json new file mode 100644 index 000000000..585c3981f --- /dev/null +++ b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json @@ -0,0 +1,1679 @@ +{ + "selectWorld.deleteButton": "selectWorld.delete", + "createWorld.customize.custom.presets": "createWorld.customize.presets", + "createWorld.customize.custom.preset.waterWorld": "createWorld.customize.preset.water_world", + "spectatorMenu.previous_page": "createWorld.customize.custom.prev", + "spectatorMenu.next_page": "createWorld.customize.custom.next", + "selectServer.empty": "selectWorld.empty", + "selectServer.edit": "selectWorld.edit", + "selectServer.delete": "selectWorld.delete", + "selectServer.deleteButton": "selectWorld.delete", + "addServer.add": "gui.done", + "disconnect.genericReason": "createWorld.customize.flat.layer", + "disconnect.quitting": "multiplayer.status.quitting", + "options.music": "soundCategory.music", + "options.fov.min": "selectWorld.mapType.normal", + "options.ao.off": "options.off", + "options.difficulty.normal": "selectWorld.mapType.normal", + "options.difficulty.hardcore": "selectWorld.gameMode.hardcore", + "options.clouds.fancy": "options.graphics.fancy", + "options.clouds.fast": "options.graphics.fast", + "options.guiScale.normal": "selectWorld.mapType.normal", + "options.particles.all": "gui.all", + "options.chat.visibility.full": "options.visible", + "options.chat.visibility.hidden": "options.hidden", + "key.mouseButton": "key.mouse", + "key.categories.multiplayer": "menu.multiplayer", + "key.categories.creative": "gameMode.creative", + "tile.air.name": "block.minecraft.air", + "tile.barrier.name": "block.minecraft.barrier", + "tile.stone.stone.name": "block.minecraft.stone", + "tile.stone.granite.name": "block.minecraft.granite", + "tile.stone.graniteSmooth.name": "block.minecraft.polished_granite", + "tile.stone.diorite.name": "block.minecraft.diorite", + "tile.stone.dioriteSmooth.name": "block.minecraft.polished_diorite", + "tile.stone.andesite.name": "block.minecraft.andesite", + "tile.stone.andesiteSmooth.name": "block.minecraft.polished_andesite", + "tile.hayBlock.name": "block.minecraft.hay_block", + "tile.grass.name": "block.minecraft.grass_block", + "tile.dirt.name": "block.minecraft.dirt", + "tile.dirt.default.name": "block.minecraft.dirt", + "tile.dirt.coarse.name": "block.minecraft.coarse_dirt", + "tile.dirt.podzol.name": "block.minecraft.podzol", + "tile.stonebrick.name": "block.minecraft.cobblestone", + "tile.sapling.oak.name": "block.minecraft.oak_sapling", + "tile.sapling.spruce.name": "block.minecraft.spruce_sapling", + "tile.sapling.birch.name": "block.minecraft.birch_sapling", + "tile.sapling.jungle.name": "block.minecraft.jungle_sapling", + "tile.sapling.acacia.name": "block.minecraft.acacia_sapling", + "tile.sapling.big_oak.name": "block.minecraft.dark_oak_sapling", + "tile.deadbush.name": "block.minecraft.dead_bush", + "tile.bedrock.name": "block.minecraft.bedrock", + "tile.water.name": "block.minecraft.water", + "tile.lava.name": "block.minecraft.lava", + "tile.sand.name": "block.minecraft.sand", + "tile.sand.default.name": "block.minecraft.sand", + "tile.sand.red.name": "block.minecraft.red_sand", + "tile.sandStone.name": "block.minecraft.sandstone", + "tile.sandStone.default.name": "block.minecraft.sandstone", + "tile.sandStone.chiseled.name": "block.minecraft.chiseled_sandstone", + "tile.sandStone.smooth.name": "block.minecraft.smooth_sandstone", + "tile.redSandStone.name": "block.minecraft.red_sandstone", + "tile.redSandStone.default.name": "block.minecraft.red_sandstone", + "tile.redSandStone.chiseled.name": "block.minecraft.chiseled_red_sandstone", + "tile.redSandStone.smooth.name": "block.minecraft.smooth_red_sandstone", + "tile.gravel.name": "block.minecraft.gravel", + "tile.oreGold.name": "block.minecraft.gold_ore", + "tile.oreIron.name": "block.minecraft.iron_ore", + "tile.oreCoal.name": "block.minecraft.coal_ore", + "tile.log.oak.name": "block.minecraft.oak_wood", + "tile.log.spruce.name": "block.minecraft.spruce_wood", + "tile.log.birch.name": "block.minecraft.birch_wood", + "tile.log.jungle.name": "block.minecraft.jungle_wood", + "tile.log.acacia.name": "block.minecraft.acacia_wood", + "tile.log.big_oak.name": "block.minecraft.dark_oak_wood", + "tile.leaves.oak.name": "block.minecraft.oak_leaves", + "tile.leaves.spruce.name": "block.minecraft.spruce_leaves", + "tile.leaves.birch.name": "block.minecraft.birch_leaves", + "tile.leaves.jungle.name": "block.minecraft.jungle_leaves", + "tile.leaves.acacia.name": "block.minecraft.acacia_leaves", + "tile.leaves.big_oak.name": "block.minecraft.dark_oak_leaves", + "tile.tallgrass.name": "block.minecraft.grass", + "tile.tallgrass.grass.name": "block.minecraft.grass", + "tile.tallgrass.fern.name": "block.minecraft.fern", + "tile.sponge.dry.name": "block.minecraft.sponge", + "tile.sponge.wet.name": "block.minecraft.wet_sponge", + "tile.glass.name": "block.minecraft.glass", + "tile.stainedGlass.black.name": "block.minecraft.black_stained_glass", + "tile.stainedGlass.red.name": "block.minecraft.red_stained_glass", + "tile.stainedGlass.green.name": "block.minecraft.green_stained_glass", + "tile.stainedGlass.brown.name": "block.minecraft.brown_stained_glass", + "tile.stainedGlass.blue.name": "block.minecraft.blue_stained_glass", + "tile.stainedGlass.purple.name": "block.minecraft.purple_stained_glass", + "tile.stainedGlass.cyan.name": "block.minecraft.cyan_stained_glass", + "tile.stainedGlass.silver.name": "block.minecraft.light_gray_stained_glass", + "tile.stainedGlass.gray.name": "block.minecraft.gray_stained_glass", + "tile.stainedGlass.pink.name": "block.minecraft.pink_stained_glass", + "tile.stainedGlass.lime.name": "block.minecraft.lime_stained_glass", + "tile.stainedGlass.yellow.name": "block.minecraft.yellow_stained_glass", + "tile.stainedGlass.lightBlue.name": "block.minecraft.light_blue_stained_glass", + "tile.stainedGlass.magenta.name": "block.minecraft.magenta_stained_glass", + "tile.stainedGlass.orange.name": "block.minecraft.orange_stained_glass", + "tile.stainedGlass.white.name": "block.minecraft.white_stained_glass", + "tile.thinStainedGlass.black.name": "block.minecraft.black_stained_glass_pane", + "tile.thinStainedGlass.red.name": "block.minecraft.red_stained_glass_pane", + "tile.thinStainedGlass.green.name": "block.minecraft.green_stained_glass_pane", + "tile.thinStainedGlass.brown.name": "block.minecraft.brown_stained_glass_pane", + "tile.thinStainedGlass.blue.name": "block.minecraft.blue_stained_glass_pane", + "tile.thinStainedGlass.purple.name": "block.minecraft.purple_stained_glass_pane", + "tile.thinStainedGlass.cyan.name": "block.minecraft.cyan_stained_glass_pane", + "tile.thinStainedGlass.silver.name": "block.minecraft.light_gray_stained_glass_pane", + "tile.thinStainedGlass.gray.name": "block.minecraft.gray_stained_glass_pane", + "tile.thinStainedGlass.pink.name": "block.minecraft.pink_stained_glass_pane", + "tile.thinStainedGlass.lime.name": "block.minecraft.lime_stained_glass_pane", + "tile.thinStainedGlass.yellow.name": "block.minecraft.yellow_stained_glass_pane", + "tile.thinStainedGlass.lightBlue.name": "block.minecraft.light_blue_stained_glass_pane", + "tile.thinStainedGlass.magenta.name": "block.minecraft.magenta_stained_glass_pane", + "tile.thinStainedGlass.orange.name": "block.minecraft.orange_stained_glass_pane", + "tile.thinStainedGlass.white.name": "block.minecraft.white_stained_glass_pane", + "tile.thinGlass.name": "block.minecraft.glass_pane", + "tile.flower1.dandelion.name": "block.minecraft.dandelion", + "tile.flower2.poppy.name": "block.minecraft.poppy", + "tile.flower2.blueOrchid.name": "block.minecraft.blue_orchid", + "tile.flower2.allium.name": "block.minecraft.allium", + "tile.flower2.houstonia.name": "block.minecraft.azure_bluet", + "tile.flower2.tulipRed.name": "block.minecraft.red_tulip", + "tile.flower2.tulipOrange.name": "block.minecraft.orange_tulip", + "tile.flower2.tulipWhite.name": "block.minecraft.white_tulip", + "tile.flower2.tulipPink.name": "block.minecraft.pink_tulip", + "tile.flower2.oxeyeDaisy.name": "block.minecraft.oxeye_daisy", + "tile.doublePlant.sunflower.name": "block.minecraft.sunflower", + "tile.doublePlant.syringa.name": "block.minecraft.lilac", + "tile.doublePlant.fern.name": "block.minecraft.large_fern", + "tile.doublePlant.rose.name": "block.minecraft.rose_bush", + "tile.doublePlant.paeonia.name": "block.minecraft.peony", + "tile.blockGold.name": "block.minecraft.gold_block", + "tile.blockIron.name": "block.minecraft.iron_block", + "tile.stoneSlab.name": "block.minecraft.stone_slab", + "tile.stoneSlab.stone.name": "block.minecraft.stone_slab", + "tile.stoneSlab.sand.name": "block.minecraft.sandstone_slab", + "tile.stoneSlab.cobble.name": "block.minecraft.cobblestone_slab", + "tile.stoneSlab.netherBrick.name": "block.minecraft.nether_brick_slab", + "tile.stoneSlab.quartz.name": "block.minecraft.quartz_slab", + "tile.stoneSlab2.red_sandstone.name": "block.minecraft.red_sandstone_slab", + "tile.brick.name": "block.minecraft.bricks", + "tile.tnt.name": "block.minecraft.tnt", + "tile.bookshelf.name": "block.minecraft.bookshelf", + "tile.obsidian.name": "block.minecraft.obsidian", + "tile.torch.name": "block.minecraft.torch", + "tile.fire.name": "block.minecraft.fire", + "tile.chest.name": "block.minecraft.chest", + "tile.chestTrap.name": "block.minecraft.trapped_chest", + "tile.redstoneDust.name": "block.minecraft.redstone_wire", + "tile.oreDiamond.name": "block.minecraft.diamond_ore", + "tile.blockCoal.name": "block.minecraft.coal_block", + "tile.blockDiamond.name": "block.minecraft.diamond_block", + "tile.workbench.name": "block.minecraft.crafting_table", + "tile.farmland.name": "block.minecraft.farmland", + "tile.furnace.name": "block.minecraft.furnace", + "tile.sign.name": "book.signButton", + "tile.ladder.name": "block.minecraft.ladder", + "tile.rail.name": "block.minecraft.rail", + "tile.goldenRail.name": "block.minecraft.powered_rail", + "tile.activatorRail.name": "block.minecraft.activator_rail", + "tile.detectorRail.name": "block.minecraft.detector_rail", + "tile.stairsStone.name": "block.minecraft.cobblestone_stairs", + "tile.stairsSandStone.name": "block.minecraft.sandstone_stairs", + "tile.stairsRedSandStone.name": "block.minecraft.red_sandstone_stairs", + "tile.lever.name": "block.minecraft.lever", + "tile.pressurePlateStone.name": "block.minecraft.stone_pressure_plate", + "tile.doorIron.name": "block.minecraft.iron_door", + "tile.oreRedstone.name": "block.minecraft.redstone_ore", + "tile.notGate.name": "block.minecraft.redstone_torch", + "tile.snow.name": "block.minecraft.snow", + "tile.woolCarpet.black.name": "block.minecraft.black_carpet", + "tile.woolCarpet.red.name": "block.minecraft.red_carpet", + "tile.woolCarpet.green.name": "block.minecraft.green_carpet", + "tile.woolCarpet.brown.name": "block.minecraft.brown_carpet", + "tile.woolCarpet.blue.name": "block.minecraft.blue_carpet", + "tile.woolCarpet.purple.name": "block.minecraft.purple_carpet", + "tile.woolCarpet.cyan.name": "block.minecraft.cyan_carpet", + "tile.woolCarpet.silver.name": "block.minecraft.light_gray_carpet", + "tile.woolCarpet.gray.name": "block.minecraft.gray_carpet", + "tile.woolCarpet.pink.name": "block.minecraft.pink_carpet", + "tile.woolCarpet.lime.name": "block.minecraft.lime_carpet", + "tile.woolCarpet.yellow.name": "block.minecraft.yellow_carpet", + "tile.woolCarpet.lightBlue.name": "block.minecraft.light_blue_carpet", + "tile.woolCarpet.magenta.name": "block.minecraft.magenta_carpet", + "tile.woolCarpet.orange.name": "block.minecraft.orange_carpet", + "tile.woolCarpet.white.name": "block.minecraft.white_carpet", + "tile.ice.name": "block.minecraft.ice", + "tile.frostedIce.name": "block.minecraft.frosted_ice", + "tile.icePacked.name": "block.minecraft.packed_ice", + "tile.cactus.name": "block.minecraft.cactus", + "tile.clay.name": "block.minecraft.clay", + "tile.clayHardenedStained.black.name": "block.minecraft.black_terracotta", + "tile.clayHardenedStained.red.name": "block.minecraft.red_terracotta", + "tile.clayHardenedStained.green.name": "block.minecraft.green_terracotta", + "tile.clayHardenedStained.brown.name": "block.minecraft.brown_terracotta", + "tile.clayHardenedStained.blue.name": "block.minecraft.blue_terracotta", + "tile.clayHardenedStained.purple.name": "block.minecraft.purple_terracotta", + "tile.clayHardenedStained.cyan.name": "block.minecraft.cyan_terracotta", + "tile.clayHardenedStained.silver.name": "block.minecraft.light_gray_terracotta", + "tile.clayHardenedStained.gray.name": "block.minecraft.gray_terracotta", + "tile.clayHardenedStained.pink.name": "block.minecraft.pink_terracotta", + "tile.clayHardenedStained.lime.name": "block.minecraft.lime_terracotta", + "tile.clayHardenedStained.yellow.name": "block.minecraft.yellow_terracotta", + "tile.clayHardenedStained.lightBlue.name": "block.minecraft.light_blue_terracotta", + "tile.clayHardenedStained.magenta.name": "block.minecraft.magenta_terracotta", + "tile.clayHardenedStained.orange.name": "block.minecraft.orange_terracotta", + "tile.clayHardenedStained.white.name": "block.minecraft.white_terracotta", + "tile.clayHardened.name": "block.minecraft.terracotta", + "tile.jukebox.name": "block.minecraft.jukebox", + "tile.fence.name": "block.minecraft.oak_fence", + "tile.spruceFence.name": "block.minecraft.spruce_fence", + "tile.birchFence.name": "block.minecraft.birch_fence", + "tile.jungleFence.name": "block.minecraft.jungle_fence", + "tile.darkOakFence.name": "block.minecraft.dark_oak_fence", + "tile.acaciaFence.name": "block.minecraft.acacia_fence", + "tile.fenceGate.name": "block.minecraft.oak_fence_gate", + "tile.spruceFenceGate.name": "block.minecraft.spruce_fence_gate", + "tile.birchFenceGate.name": "block.minecraft.birch_fence_gate", + "tile.jungleFenceGate.name": "block.minecraft.jungle_fence_gate", + "tile.darkOakFenceGate.name": "block.minecraft.dark_oak_fence_gate", + "tile.acaciaFenceGate.name": "block.minecraft.acacia_fence_gate", + "tile.pumpkinStem.name": "block.minecraft.pumpkin_stem", + "tile.pumpkin.name": "block.minecraft.pumpkin", + "tile.litpumpkin.name": "block.minecraft.jack_o_lantern", + "tile.hellrock.name": "block.minecraft.netherrack", + "tile.hellsand.name": "block.minecraft.soul_sand", + "tile.lightgem.name": "block.minecraft.glowstone", + "tile.cloth.black.name": "block.minecraft.black_wool", + "tile.cloth.red.name": "block.minecraft.red_wool", + "tile.cloth.green.name": "block.minecraft.green_wool", + "tile.cloth.brown.name": "block.minecraft.brown_wool", + "tile.cloth.blue.name": "block.minecraft.blue_wool", + "tile.cloth.purple.name": "block.minecraft.purple_wool", + "tile.cloth.cyan.name": "block.minecraft.cyan_wool", + "tile.cloth.silver.name": "block.minecraft.light_gray_wool", + "tile.cloth.gray.name": "block.minecraft.gray_wool", + "tile.cloth.pink.name": "block.minecraft.pink_wool", + "tile.cloth.lime.name": "block.minecraft.lime_wool", + "tile.cloth.yellow.name": "block.minecraft.yellow_wool", + "tile.cloth.lightBlue.name": "block.minecraft.light_blue_wool", + "tile.cloth.magenta.name": "block.minecraft.magenta_wool", + "tile.cloth.orange.name": "block.minecraft.orange_wool", + "tile.cloth.white.name": "block.minecraft.white_wool", + "tile.oreLapis.name": "block.minecraft.lapis_ore", + "tile.blockLapis.name": "block.minecraft.lapis_block", + "tile.dispenser.name": "block.minecraft.dispenser", + "tile.dropper.name": "block.minecraft.dropper", + "tile.musicBlock.name": "block.minecraft.note_block", + "tile.cake.name": "block.minecraft.cake", + "tile.bed.occupied": "block.minecraft.bed.occupied", + "tile.bed.notValid": "block.minecraft.bed.not_valid", + "tile.ironTrapdoor.name": "block.minecraft.iron_trapdoor", + "tile.web.name": "block.minecraft.cobweb", + "tile.stonebricksmooth.name": "block.minecraft.stone_bricks", + "tile.stonebricksmooth.default.name": "block.minecraft.stone_bricks", + "tile.stonebricksmooth.mossy.name": "block.minecraft.mossy_stone_bricks", + "tile.stonebricksmooth.cracked.name": "block.minecraft.cracked_stone_bricks", + "tile.stonebricksmooth.chiseled.name": "block.minecraft.chiseled_stone_bricks", + "tile.pistonBase.name": "block.minecraft.piston", + "tile.pistonStickyBase.name": "block.minecraft.sticky_piston", + "tile.fenceIron.name": "block.minecraft.iron_bars", + "tile.melon.name": "block.minecraft.melon", + "tile.stairsBrick.name": "block.minecraft.brick_stairs", + "tile.stairsStoneBrickSmooth.name": "block.minecraft.stone_brick_stairs", + "tile.vine.name": "block.minecraft.vine", + "tile.netherBrick.name": "item.minecraft.nether_brick", + "tile.netherFence.name": "block.minecraft.nether_brick_fence", + "tile.stairsNetherBrick.name": "block.minecraft.nether_brick_stairs", + "tile.netherStalk.name": "block.minecraft.nether_wart", + "tile.cauldron.name": "block.minecraft.cauldron", + "tile.anvil.name": "block.minecraft.anvil", + "tile.anvil.intact.name": "block.minecraft.anvil", + "tile.whiteStone.name": "block.minecraft.end_stone", + "tile.endPortalFrame.name": "block.minecraft.end_portal", + "tile.mycel.name": "block.minecraft.mycelium", + "tile.waterlily.name": "block.minecraft.lily_pad", + "tile.dragonEgg.name": "block.minecraft.dragon_egg", + "tile.redstoneLight.name": "block.minecraft.redstone_lamp", + "tile.cocoa.name": "block.minecraft.cocoa", + "tile.enderChest.name": "block.minecraft.ender_chest", + "tile.oreEmerald.name": "block.minecraft.emerald_ore", + "tile.blockEmerald.name": "block.minecraft.emerald_block", + "tile.blockRedstone.name": "block.minecraft.redstone_block", + "tile.tripWire.name": "block.minecraft.tripwire", + "tile.tripWireSource.name": "block.minecraft.tripwire_hook", + "tile.commandBlock.name": "block.minecraft.command_block", + "tile.repeatingCommandBlock.name": "block.minecraft.repeating_command_block", + "tile.chainCommandBlock.name": "block.minecraft.chain_command_block", + "tile.beacon.name": "block.minecraft.beacon", + "tile.beacon.primary": "block.minecraft.beacon.primary", + "tile.beacon.secondary": "block.minecraft.beacon.secondary", + "tile.cobbleWall.normal.name": "block.minecraft.cobblestone_wall", + "tile.cobbleWall.mossy.name": "block.minecraft.mossy_cobblestone_wall", + "tile.carrots.name": "block.minecraft.carrots", + "tile.potatoes.name": "block.minecraft.potatoes", + "tile.netherquartz.name": "block.minecraft.nether_quartz_ore", + "tile.hopper.name": "block.minecraft.hopper", + "tile.quartzBlock.name": "block.minecraft.quartz_block", + "tile.quartzBlock.default.name": "block.minecraft.quartz_block", + "tile.quartzBlock.chiseled.name": "block.minecraft.chiseled_quartz_block", + "tile.stairsQuartz.name": "block.minecraft.quartz_stairs", + "tile.slime.name": "block.minecraft.slime_block", + "tile.prismarine.rough.name": "block.minecraft.prismarine", + "tile.prismarine.bricks.name": "block.minecraft.prismarine_bricks", + "tile.prismarine.dark.name": "block.minecraft.dark_prismarine", + "tile.seaLantern.name": "block.minecraft.sea_lantern", + "tile.endRod.name": "block.minecraft.end_rod", + "tile.chorusPlant.name": "block.minecraft.chorus_plant", + "tile.chorusFlower.name": "block.minecraft.chorus_flower", + "tile.purpurBlock.name": "block.minecraft.purpur_block", + "tile.purpurPillar.name": "block.minecraft.purpur_pillar", + "tile.stairsPurpur.name": "block.minecraft.purpur_stairs", + "tile.purpurSlab.name": "block.minecraft.purpur_slab", + "tile.endBricks.name": "block.minecraft.end_stone_bricks", + "tile.beetroots.name": "block.minecraft.beetroots", + "tile.grassPath.name": "block.minecraft.grass_path", + "tile.magma.name": "block.minecraft.magma_block", + "tile.netherWartBlock.name": "block.minecraft.nether_wart_block", + "tile.boneBlock.name": "block.minecraft.bone_block", + "tile.observer.name": "block.minecraft.observer", + "tile.shulkerBoxWhite.name": "block.minecraft.white_shulker_box", + "tile.shulkerBoxOrange.name": "block.minecraft.orange_shulker_box", + "tile.shulkerBoxMagenta.name": "block.minecraft.magenta_shulker_box", + "tile.shulkerBoxLightBlue.name": "block.minecraft.light_blue_shulker_box", + "tile.shulkerBoxYellow.name": "block.minecraft.yellow_shulker_box", + "tile.shulkerBoxLime.name": "block.minecraft.lime_shulker_box", + "tile.shulkerBoxPink.name": "block.minecraft.pink_shulker_box", + "tile.shulkerBoxGray.name": "block.minecraft.gray_shulker_box", + "tile.shulkerBoxSilver.name": "block.minecraft.light_gray_shulker_box", + "tile.shulkerBoxCyan.name": "block.minecraft.cyan_shulker_box", + "tile.shulkerBoxPurple.name": "block.minecraft.purple_shulker_box", + "tile.shulkerBoxBlue.name": "block.minecraft.blue_shulker_box", + "tile.shulkerBoxBrown.name": "block.minecraft.brown_shulker_box", + "tile.shulkerBoxGreen.name": "block.minecraft.green_shulker_box", + "tile.shulkerBoxRed.name": "block.minecraft.red_shulker_box", + "tile.shulkerBoxBlack.name": "block.minecraft.black_shulker_box", + "tile.glazedTerracottaWhite.name": "block.minecraft.white_glazed_terracotta", + "tile.glazedTerracottaOrange.name": "block.minecraft.orange_glazed_terracotta", + "tile.glazedTerracottaMagenta.name": "block.minecraft.magenta_glazed_terracotta", + "tile.glazedTerracottaLightBlue.name": "block.minecraft.light_blue_glazed_terracotta", + "tile.glazedTerracottaYellow.name": "block.minecraft.yellow_glazed_terracotta", + "tile.glazedTerracottaLime.name": "block.minecraft.lime_glazed_terracotta", + "tile.glazedTerracottaPink.name": "block.minecraft.pink_glazed_terracotta", + "tile.glazedTerracottaGray.name": "block.minecraft.gray_glazed_terracotta", + "tile.glazedTerracottaSilver.name": "block.minecraft.light_gray_glazed_terracotta", + "tile.glazedTerracottaCyan.name": "block.minecraft.cyan_glazed_terracotta", + "tile.glazedTerracottaPurple.name": "block.minecraft.purple_glazed_terracotta", + "tile.glazedTerracottaBlue.name": "block.minecraft.blue_glazed_terracotta", + "tile.glazedTerracottaBrown.name": "block.minecraft.brown_glazed_terracotta", + "tile.glazedTerracottaGreen.name": "block.minecraft.green_glazed_terracotta", + "tile.glazedTerracottaRed.name": "block.minecraft.red_glazed_terracotta", + "tile.glazedTerracottaBlack.name": "block.minecraft.black_glazed_terracotta", + "tile.concrete.black.name": "block.minecraft.black_concrete", + "tile.concrete.red.name": "block.minecraft.red_concrete", + "tile.concrete.green.name": "block.minecraft.green_concrete", + "tile.concrete.brown.name": "block.minecraft.brown_concrete", + "tile.concrete.blue.name": "block.minecraft.blue_concrete", + "tile.concrete.purple.name": "block.minecraft.purple_concrete", + "tile.concrete.cyan.name": "block.minecraft.cyan_concrete", + "tile.concrete.silver.name": "block.minecraft.light_gray_concrete", + "tile.concrete.gray.name": "block.minecraft.gray_concrete", + "tile.concrete.pink.name": "block.minecraft.pink_concrete", + "tile.concrete.lime.name": "block.minecraft.lime_concrete", + "tile.concrete.yellow.name": "block.minecraft.yellow_concrete", + "tile.concrete.lightBlue.name": "block.minecraft.light_blue_concrete", + "tile.concrete.magenta.name": "block.minecraft.magenta_concrete", + "tile.concrete.orange.name": "block.minecraft.orange_concrete", + "tile.concrete.white.name": "block.minecraft.white_concrete", + "tile.concretePowder.black.name": "block.minecraft.black_concrete_powder", + "tile.concretePowder.red.name": "block.minecraft.red_concrete_powder", + "tile.concretePowder.green.name": "block.minecraft.green_concrete_powder", + "tile.concretePowder.brown.name": "block.minecraft.brown_concrete_powder", + "tile.concretePowder.blue.name": "block.minecraft.blue_concrete_powder", + "tile.concretePowder.purple.name": "block.minecraft.purple_concrete_powder", + "tile.concretePowder.cyan.name": "block.minecraft.cyan_concrete_powder", + "tile.concretePowder.silver.name": "block.minecraft.light_gray_concrete_powder", + "tile.concretePowder.gray.name": "block.minecraft.gray_concrete_powder", + "tile.concretePowder.pink.name": "block.minecraft.pink_concrete_powder", + "tile.concretePowder.lime.name": "block.minecraft.lime_concrete_powder", + "tile.concretePowder.yellow.name": "block.minecraft.yellow_concrete_powder", + "tile.concretePowder.lightBlue.name": "block.minecraft.light_blue_concrete_powder", + "tile.concretePowder.magenta.name": "block.minecraft.magenta_concrete_powder", + "tile.concretePowder.orange.name": "block.minecraft.orange_concrete_powder", + "tile.concretePowder.white.name": "block.minecraft.white_concrete_powder", + "tile.structureVoid.name": "block.minecraft.structure_void", + "tile.structureBlock.name": "block.minecraft.structure_block", + "item.nameTag.name": "item.minecraft.name_tag", + "item.leash.name": "item.minecraft.lead", + "item.shovelIron.name": "item.minecraft.iron_shovel", + "item.pickaxeIron.name": "item.minecraft.iron_pickaxe", + "item.hatchetIron.name": "item.minecraft.iron_axe", + "item.flintAndSteel.name": "item.minecraft.flint_and_steel", + "item.apple.name": "item.minecraft.apple", + "item.cookie.name": "item.minecraft.cookie", + "item.bow.name": "item.minecraft.bow", + "item.arrow.name": "item.minecraft.arrow", + "item.spectral_arrow.name": "item.minecraft.spectral_arrow", + "item.tipped_arrow.name": "item.minecraft.tipped_arrow", + "item.coal.name": "item.minecraft.coal", + "item.charcoal.name": "item.minecraft.charcoal", + "item.diamond.name": "item.minecraft.diamond", + "item.emerald.name": "item.minecraft.emerald", + "item.ingotIron.name": "item.minecraft.iron_ingot", + "item.ingotGold.name": "item.minecraft.gold_ingot", + "item.swordIron.name": "item.minecraft.iron_sword", + "item.swordWood.name": "item.minecraft.wooden_sword", + "item.shovelWood.name": "item.minecraft.wooden_shovel", + "item.pickaxeWood.name": "item.minecraft.wooden_pickaxe", + "item.hatchetWood.name": "item.minecraft.wooden_axe", + "item.swordStone.name": "item.minecraft.stone_sword", + "item.shovelStone.name": "item.minecraft.stone_shovel", + "item.pickaxeStone.name": "item.minecraft.stone_pickaxe", + "item.hatchetStone.name": "item.minecraft.stone_axe", + "item.swordDiamond.name": "item.minecraft.diamond_sword", + "item.shovelDiamond.name": "item.minecraft.diamond_shovel", + "item.pickaxeDiamond.name": "item.minecraft.diamond_pickaxe", + "item.hatchetDiamond.name": "item.minecraft.diamond_axe", + "item.stick.name": "item.minecraft.stick", + "item.bowl.name": "item.minecraft.bowl", + "item.mushroomStew.name": "item.minecraft.mushroom_stew", + "item.swordGold.name": "item.minecraft.golden_sword", + "item.shovelGold.name": "item.minecraft.golden_shovel", + "item.pickaxeGold.name": "item.minecraft.golden_pickaxe", + "item.hatchetGold.name": "item.minecraft.golden_axe", + "item.string.name": "item.minecraft.string", + "item.feather.name": "item.minecraft.feather", + "item.sulphur.name": "item.minecraft.gunpowder", + "item.hoeWood.name": "item.minecraft.wooden_hoe", + "item.hoeStone.name": "item.minecraft.stone_hoe", + "item.hoeIron.name": "item.minecraft.iron_hoe", + "item.hoeDiamond.name": "item.minecraft.diamond_hoe", + "item.hoeGold.name": "item.minecraft.golden_hoe", + "item.seeds_pumpkin.name": "item.minecraft.pumpkin_seeds", + "item.seeds_melon.name": "item.minecraft.melon_seeds", + "item.melon.name": "block.minecraft.melon", + "item.wheat.name": "item.minecraft.wheat", + "item.bread.name": "item.minecraft.bread", + "item.helmetCloth.name": "item.minecraft.leather_helmet", + "item.chestplateCloth.name": "item.minecraft.leather_chestplate", + "item.leggingsCloth.name": "item.minecraft.leather_leggings", + "item.bootsCloth.name": "item.minecraft.leather_boots", + "item.helmetIron.name": "item.minecraft.iron_helmet", + "item.chestplateIron.name": "item.minecraft.iron_chestplate", + "item.leggingsIron.name": "item.minecraft.iron_leggings", + "item.bootsIron.name": "item.minecraft.iron_boots", + "item.helmetDiamond.name": "item.minecraft.diamond_helmet", + "item.chestplateDiamond.name": "item.minecraft.diamond_chestplate", + "item.leggingsDiamond.name": "item.minecraft.diamond_leggings", + "item.bootsDiamond.name": "item.minecraft.diamond_boots", + "item.helmetGold.name": "item.minecraft.golden_helmet", + "item.chestplateGold.name": "item.minecraft.golden_chestplate", + "item.leggingsGold.name": "item.minecraft.golden_leggings", + "item.bootsGold.name": "item.minecraft.golden_boots", + "item.flint.name": "item.minecraft.flint", + "item.porkchopRaw.name": "item.minecraft.porkchop", + "item.porkchopCooked.name": "item.minecraft.cooked_porkchop", + "item.chickenRaw.name": "item.minecraft.chicken", + "item.chickenCooked.name": "item.minecraft.cooked_chicken", + "item.muttonRaw.name": "item.minecraft.mutton", + "item.muttonCooked.name": "item.minecraft.cooked_mutton", + "item.rabbitRaw.name": "item.minecraft.rabbit", + "item.rabbitCooked.name": "item.minecraft.cooked_rabbit", + "item.rabbitStew.name": "item.minecraft.rabbit_stew", + "item.rabbitFoot.name": "item.minecraft.rabbit_foot", + "item.rabbitHide.name": "item.minecraft.rabbit_hide", + "item.beefRaw.name": "item.minecraft.beef", + "item.beefCooked.name": "item.minecraft.cooked_beef", + "item.painting.name": "item.minecraft.painting", + "item.frame.name": "item.minecraft.item_frame", + "item.appleGold.name": "item.minecraft.golden_apple", + "item.sign.name": "book.signButton", + "item.doorOak.name": "block.minecraft.oak_door", + "item.doorSpruce.name": "block.minecraft.spruce_door", + "item.doorBirch.name": "block.minecraft.birch_door", + "item.doorJungle.name": "block.minecraft.jungle_door", + "item.doorAcacia.name": "block.minecraft.acacia_door", + "item.doorDarkOak.name": "block.minecraft.dark_oak_door", + "item.bucket.name": "item.minecraft.bucket", + "item.bucketWater.name": "item.minecraft.water_bucket", + "item.bucketLava.name": "item.minecraft.lava_bucket", + "item.minecart.name": "item.minecraft.minecart", + "item.saddle.name": "item.minecraft.saddle", + "item.doorIron.name": "block.minecraft.iron_door", + "item.redstone.name": "item.minecraft.redstone", + "item.snowball.name": "item.minecraft.snowball", + "item.boat.oak.name": "item.minecraft.oak_boat", + "item.boat.spruce.name": "item.minecraft.spruce_boat", + "item.boat.birch.name": "item.minecraft.birch_boat", + "item.boat.jungle.name": "item.minecraft.jungle_boat", + "item.boat.acacia.name": "item.minecraft.acacia_boat", + "item.boat.dark_oak.name": "item.minecraft.dark_oak_boat", + "item.leather.name": "item.minecraft.leather", + "item.brick.name": "item.minecraft.brick", + "item.clay.name": "block.minecraft.clay", + "item.paper.name": "item.minecraft.paper", + "item.book.name": "item.minecraft.book", + "item.slimeball.name": "item.minecraft.slime_ball", + "item.minecartChest.name": "item.minecraft.chest_minecart", + "item.minecartFurnace.name": "item.minecraft.furnace_minecart", + "item.minecartTnt.name": "item.minecraft.tnt_minecart", + "item.minecartHopper.name": "item.minecraft.hopper_minecart", + "item.minecartCommandBlock.name": "item.minecraft.command_block_minecart", + "item.egg.name": "item.minecraft.egg", + "item.compass.name": "item.minecraft.compass", + "item.fishingRod.name": "item.minecraft.fishing_rod", + "item.clock.name": "item.minecraft.clock", + "item.yellowDust.name": "item.minecraft.glowstone_dust", + "item.fish.salmon.raw.name": "item.minecraft.salmon", + "item.fish.pufferfish.raw.name": "item.minecraft.pufferfish", + "item.fish.salmon.cooked.name": "item.minecraft.cooked_salmon", + "item.record.name": "item.minecraft.music_disc_13", + "item.record.13.desc": "item.minecraft.music_disc_13.desc", + "item.record.cat.desc": "item.minecraft.music_disc_cat.desc", + "item.record.blocks.desc": "item.minecraft.music_disc_blocks.desc", + "item.record.chirp.desc": "item.minecraft.music_disc_chirp.desc", + "item.record.far.desc": "item.minecraft.music_disc_far.desc", + "item.record.mall.desc": "item.minecraft.music_disc_mall.desc", + "item.record.mellohi.desc": "item.minecraft.music_disc_mellohi.desc", + "item.record.stal.desc": "item.minecraft.music_disc_stal.desc", + "item.record.strad.desc": "item.minecraft.music_disc_strad.desc", + "item.record.ward.desc": "item.minecraft.music_disc_ward.desc", + "item.record.11.desc": "item.minecraft.music_disc_11.desc", + "item.record.wait.desc": "item.minecraft.music_disc_wait.desc", + "item.bone.name": "item.minecraft.bone", + "item.dyePowder.black.name": "item.minecraft.ink_sac", + "item.dyePowder.red.name": "item.minecraft.rose_red", + "item.dyePowder.green.name": "item.minecraft.cactus_green", + "item.dyePowder.brown.name": "item.minecraft.cocoa_beans", + "item.dyePowder.blue.name": "item.minecraft.lapis_lazuli", + "item.dyePowder.purple.name": "item.minecraft.purple_dye", + "item.dyePowder.cyan.name": "item.minecraft.cyan_dye", + "item.dyePowder.silver.name": "item.minecraft.light_gray_dye", + "item.dyePowder.gray.name": "item.minecraft.gray_dye", + "item.dyePowder.pink.name": "item.minecraft.pink_dye", + "item.dyePowder.lime.name": "item.minecraft.lime_dye", + "item.dyePowder.yellow.name": "item.minecraft.dandelion_yellow", + "item.dyePowder.lightBlue.name": "item.minecraft.light_blue_dye", + "item.dyePowder.magenta.name": "item.minecraft.magenta_dye", + "item.dyePowder.orange.name": "item.minecraft.orange_dye", + "item.dyePowder.white.name": "item.minecraft.bone_meal", + "item.sugar.name": "item.minecraft.sugar", + "item.cake.name": "block.minecraft.cake", + "item.bed.black.name": "block.minecraft.black_bed", + "item.bed.red.name": "block.minecraft.red_bed", + "item.bed.green.name": "block.minecraft.green_bed", + "item.bed.brown.name": "block.minecraft.brown_bed", + "item.bed.blue.name": "block.minecraft.blue_bed", + "item.bed.purple.name": "block.minecraft.purple_bed", + "item.bed.cyan.name": "block.minecraft.cyan_bed", + "item.bed.silver.name": "block.minecraft.light_gray_bed", + "item.bed.gray.name": "block.minecraft.gray_bed", + "item.bed.pink.name": "block.minecraft.pink_bed", + "item.bed.lime.name": "block.minecraft.lime_bed", + "item.bed.yellow.name": "block.minecraft.yellow_bed", + "item.bed.lightBlue.name": "block.minecraft.light_blue_bed", + "item.bed.magenta.name": "block.minecraft.magenta_bed", + "item.bed.orange.name": "block.minecraft.orange_bed", + "item.bed.white.name": "block.minecraft.white_bed", + "item.diode.name": "block.minecraft.repeater", + "item.comparator.name": "block.minecraft.comparator", + "item.map.name": "item.minecraft.filled_map", + "item.shears.name": "item.minecraft.shears", + "item.rottenFlesh.name": "item.minecraft.rotten_flesh", + "item.enderPearl.name": "item.minecraft.ender_pearl", + "item.blazeRod.name": "item.minecraft.blaze_rod", + "item.ghastTear.name": "item.minecraft.ghast_tear", + "item.netherStalkSeeds.name": "block.minecraft.nether_wart", + "item.potion.name": "item.minecraft.potion", + "item.splash_potion.name": "item.minecraft.splash_potion", + "item.lingering_potion.name": "item.minecraft.lingering_potion", + "item.end_crystal.name": "item.minecraft.end_crystal", + "item.goldNugget.name": "item.minecraft.gold_nugget", + "item.glassBottle.name": "item.minecraft.glass_bottle", + "item.spiderEye.name": "item.minecraft.spider_eye", + "item.fermentedSpiderEye.name": "item.minecraft.fermented_spider_eye", + "item.blazePowder.name": "item.minecraft.blaze_powder", + "item.magmaCream.name": "item.minecraft.magma_cream", + "item.cauldron.name": "block.minecraft.cauldron", + "item.brewingStand.name": "block.minecraft.brewing_stand", + "item.eyeOfEnder.name": "item.minecraft.ender_eye", + "item.expBottle.name": "item.minecraft.experience_bottle", + "item.fireball.name": "item.minecraft.fire_charge", + "item.writingBook.name": "item.minecraft.writable_book", + "item.writtenBook.name": "item.minecraft.written_book", + "item.flowerPot.name": "block.minecraft.flower_pot", + "item.emptyMap.name": "item.minecraft.map", + "item.carrots.name": "item.minecraft.carrot", + "item.carrotGolden.name": "item.minecraft.golden_carrot", + "item.potato.name": "item.minecraft.potato", + "item.potatoBaked.name": "item.minecraft.baked_potato", + "item.potatoPoisonous.name": "item.minecraft.poisonous_potato", + "item.skull.skeleton.name": "block.minecraft.skeleton_skull", + "item.skull.wither.name": "block.minecraft.wither_skeleton_skull", + "item.skull.zombie.name": "block.minecraft.zombie_head", + "item.skull.player.name": "block.minecraft.player_head.named", + "item.skull.creeper.name": "block.minecraft.creeper_head", + "item.skull.dragon.name": "block.minecraft.dragon_head", + "item.carrotOnAStick.name": "item.minecraft.carrot_on_a_stick", + "item.netherStar.name": "item.minecraft.nether_star", + "item.pumpkinPie.name": "item.minecraft.pumpkin_pie", + "item.enchantedBook.name": "item.minecraft.enchanted_book", + "item.fireworks.name": "item.minecraft.firework_rocket", + "item.fireworks.flight": "item.minecraft.firework_rocket.flight", + "item.fireworksCharge.name": "item.minecraft.firework_star", + "item.fireworksCharge.black": "item.minecraft.firework_star.black", + "item.fireworksCharge.red": "item.minecraft.firework_star.red", + "item.fireworksCharge.green": "item.minecraft.firework_star.green", + "item.fireworksCharge.brown": "item.minecraft.firework_star.brown", + "item.fireworksCharge.blue": "item.minecraft.firework_star.blue", + "item.fireworksCharge.purple": "item.minecraft.firework_star.purple", + "item.fireworksCharge.cyan": "item.minecraft.firework_star.cyan", + "item.fireworksCharge.silver": "item.minecraft.firework_star.light_gray", + "item.fireworksCharge.gray": "item.minecraft.firework_star.gray", + "item.fireworksCharge.pink": "item.minecraft.firework_star.pink", + "item.fireworksCharge.lime": "item.minecraft.firework_star.lime", + "item.fireworksCharge.yellow": "item.minecraft.firework_star.yellow", + "item.fireworksCharge.lightBlue": "item.minecraft.firework_star.light_blue", + "item.fireworksCharge.magenta": "item.minecraft.firework_star.magenta", + "item.fireworksCharge.orange": "item.minecraft.firework_star.orange", + "item.fireworksCharge.white": "item.minecraft.firework_star.white", + "item.fireworksCharge.customColor": "item.minecraft.firework_star.custom_color", + "item.fireworksCharge.fadeTo": "item.minecraft.firework_star.fade_to", + "item.fireworksCharge.flicker": "item.minecraft.firework_star.flicker", + "item.fireworksCharge.trail": "item.minecraft.firework_star.trail", + "item.fireworksCharge.type.0": "item.minecraft.firework_star.shape.small_ball", + "item.fireworksCharge.type.1": "item.minecraft.firework_star.shape.large_ball", + "item.fireworksCharge.type.2": "item.minecraft.firework_star.shape.star", + "item.fireworksCharge.type.3": "item.minecraft.firework_star.shape.creeper", + "item.fireworksCharge.type.4": "item.minecraft.firework_star.shape.burst", + "item.fireworksCharge.type": "item.minecraft.firework_star.shape", + "item.netherbrick.name": "item.minecraft.nether_brick", + "item.netherquartz.name": "item.minecraft.quartz", + "item.armorStand.name": "item.minecraft.armor_stand", + "item.horsearmormetal.name": "item.minecraft.iron_horse_armor", + "item.horsearmordiamond.name": "item.minecraft.diamond_horse_armor", + "item.prismarineShard.name": "item.minecraft.prismarine_shard", + "item.prismarineCrystals.name": "item.minecraft.prismarine_crystals", + "item.chorusFruit.name": "item.minecraft.chorus_fruit", + "item.chorusFruitPopped.name": "item.minecraft.popped_chorus_fruit", + "item.beetroot.name": "item.minecraft.beetroot", + "item.beetroot_seeds.name": "item.minecraft.beetroot_seeds", + "item.beetroot_soup.name": "item.minecraft.beetroot_soup", + "item.dragon_breath.name": "item.minecraft.dragon_breath", + "item.elytra.name": "item.minecraft.elytra", + "item.totem.name": "item.minecraft.totem_of_undying", + "item.shulkerShell.name": "item.minecraft.shulker_shell", + "item.ironNugget.name": "item.minecraft.iron_nugget", + "item.knowledgeBook.name": "item.minecraft.knowledge_book", + "container.inventory": "key.categories.inventory", + "container.dispenser": "block.minecraft.dispenser", + "container.dropper": "block.minecraft.dropper", + "container.furnace": "block.minecraft.furnace", + "container.brewing": "block.minecraft.brewing_stand", + "container.chest": "block.minecraft.chest", + "container.enderchest": "block.minecraft.ender_chest", + "container.beacon": "block.minecraft.beacon", + "container.shulkerBox": "block.minecraft.shulker_box", + "structure_block.mode.save": "selectWorld.edit.save", + "entity.Item.name": "entity.minecraft.item", + "entity.XPOrb.name": "entity.minecraft.experience_orb", + "entity.SmallFireball.name": "entity.minecraft.small_fireball", + "entity.Fireball.name": "entity.minecraft.fireball", + "entity.DragonFireball.name": "entity.minecraft.dragon_fireball", + "entity.ThrownPotion.name": "item.minecraft.potion", + "entity.Arrow.name": "item.minecraft.arrow", + "entity.Snowball.name": "item.minecraft.snowball", + "entity.Painting.name": "item.minecraft.painting", + "entity.ArmorStand.name": "item.minecraft.armor_stand", + "entity.Creeper.name": "entity.minecraft.creeper", + "entity.Skeleton.name": "entity.minecraft.skeleton", + "entity.WitherSkeleton.name": "entity.minecraft.wither_skeleton", + "entity.Stray.name": "entity.minecraft.stray", + "entity.Spider.name": "entity.minecraft.spider", + "entity.Giant.name": "entity.minecraft.giant", + "entity.Zombie.name": "entity.minecraft.zombie", + "entity.Husk.name": "entity.minecraft.husk", + "entity.Slime.name": "entity.minecraft.slime", + "entity.Ghast.name": "entity.minecraft.ghast", + "entity.PigZombie.name": "entity.minecraft.zombie_pigman", + "entity.Enderman.name": "entity.minecraft.enderman", + "entity.Endermite.name": "entity.minecraft.endermite", + "entity.Silverfish.name": "entity.minecraft.silverfish", + "entity.CaveSpider.name": "entity.minecraft.cave_spider", + "entity.Blaze.name": "entity.minecraft.blaze", + "entity.LavaSlime.name": "entity.minecraft.magma_cube", + "entity.MushroomCow.name": "entity.minecraft.mooshroom", + "entity.Villager.name": "entity.minecraft.villager", + "entity.ZombieVillager.name": "entity.minecraft.zombie_villager", + "entity.VillagerGolem.name": "entity.minecraft.iron_golem", + "entity.SnowMan.name": "entity.minecraft.snow_golem", + "entity.EnderDragon.name": "entity.minecraft.ender_dragon", + "entity.WitherBoss.name": "entity.minecraft.wither", + "entity.Witch.name": "entity.minecraft.witch", + "entity.Guardian.name": "entity.minecraft.guardian", + "entity.ElderGuardian.name": "entity.minecraft.elder_guardian", + "entity.Shulker.name": "entity.minecraft.shulker", + "entity.PolarBear.name": "entity.minecraft.polar_bear", + "entity.EvocationIllager.name": "entity.minecraft.evoker", + "entity.Vex.name": "entity.minecraft.vex", + "entity.VindicationIllager.name": "entity.minecraft.vindicator", + "entity.Parrot.name": "entity.minecraft.parrot", + "entity.IllusionIllager.name": "entity.minecraft.illusioner", + "entity.Villager.farmer": "entity.minecraft.villager.farmer", + "entity.Villager.fisherman": "entity.minecraft.villager.fisherman", + "entity.Villager.shepherd": "entity.minecraft.villager.shepherd", + "entity.Villager.fletcher": "entity.minecraft.villager.fletcher", + "entity.Villager.librarian": "entity.minecraft.villager.librarian", + "entity.Villager.cleric": "entity.minecraft.villager.cleric", + "entity.Villager.armor": "entity.minecraft.villager.armorer", + "entity.Villager.weapon": "entity.minecraft.villager.weapon_smith", + "entity.Villager.tool": "entity.minecraft.villager.tool_smith", + "entity.Villager.butcher": "entity.minecraft.villager.butcher", + "entity.Villager.leather": "entity.minecraft.villager.leatherworker", + "entity.Villager.nitwit": "entity.minecraft.villager.nitwit", + "entity.Villager.cartographer": "entity.minecraft.villager.cartographer", + "entity.Pig.name": "entity.minecraft.pig", + "entity.Sheep.name": "entity.minecraft.sheep", + "entity.Cow.name": "entity.minecraft.cow", + "entity.Chicken.name": "entity.minecraft.chicken", + "entity.Squid.name": "entity.minecraft.squid", + "entity.Wolf.name": "entity.minecraft.wolf", + "entity.Ozelot.name": "entity.minecraft.ocelot", + "entity.Cat.name": "entity.minecraft.cat", + "entity.Bat.name": "entity.minecraft.bat", + "entity.Horse.name": "entity.minecraft.horse", + "entity.Donkey.name": "entity.minecraft.donkey", + "entity.Mule.name": "entity.minecraft.mule", + "entity.SkeletonHorse.name": "entity.minecraft.skeleton_horse", + "entity.ZombieHorse.name": "entity.minecraft.zombie_horse", + "entity.Rabbit.name": "entity.minecraft.rabbit", + "entity.KillerBunny.name": "entity.minecraft.killer_bunny", + "entity.Llama.name": "entity.minecraft.llama", + "entity.FallingSand.name": "entity.minecraft.falling_block", + "entity.Minecart.name": "item.minecraft.minecart", + "entity.MinecartHopper.name": "item.minecraft.hopper_minecart", + "entity.MinecartChest.name": "item.minecraft.chest_minecart", + "entity.Boat.name": "entity.minecraft.boat", + "entity.generic.name": "selectWorld.versionUnknown", + "death.attack.player": "death.attack.mob", + "death.attack.player.item": "death.attack.mob.item", + "effect.moveSpeed": "effect.minecraft.speed", + "effect.moveSlowdown": "effect.minecraft.slowness", + "effect.digSpeed": "effect.minecraft.haste", + "effect.digSlowDown": "effect.minecraft.mining_fatigue", + "effect.damageBoost": "effect.minecraft.strength", + "effect.heal": "effect.minecraft.instant_health", + "effect.harm": "effect.minecraft.instant_damage", + "effect.jump": "effect.minecraft.jump_boost", + "effect.confusion": "effect.minecraft.nausea", + "effect.regeneration": "effect.minecraft.regeneration", + "effect.resistance": "effect.minecraft.resistance", + "effect.fireResistance": "effect.minecraft.fire_resistance", + "effect.waterBreathing": "effect.minecraft.water_breathing", + "effect.invisibility": "effect.minecraft.invisibility", + "effect.blindness": "effect.minecraft.blindness", + "effect.nightVision": "effect.minecraft.night_vision", + "effect.hunger": "effect.minecraft.hunger", + "effect.weakness": "effect.minecraft.weakness", + "effect.poison": "effect.minecraft.poison", + "effect.wither": "entity.minecraft.wither", + "effect.healthBoost": "effect.minecraft.health_boost", + "effect.absorption": "effect.minecraft.absorption", + "effect.saturation": "options.saturation", + "effect.glowing": "effect.minecraft.glowing", + "effect.luck": "effect.minecraft.luck", + "effect.unluck": "effect.minecraft.unluck", + "effect.levitation": "effect.minecraft.levitation", + "tipped_arrow.effect.empty": "item.minecraft.tipped_arrow.effect.empty", + "tipped_arrow.effect.water": "item.minecraft.tipped_arrow.effect.water", + "tipped_arrow.effect.mundane": "item.minecraft.tipped_arrow", + "tipped_arrow.effect.thick": "item.minecraft.tipped_arrow", + "tipped_arrow.effect.awkward": "item.minecraft.tipped_arrow", + "tipped_arrow.effect.night_vision": "item.minecraft.tipped_arrow.effect.night_vision", + "tipped_arrow.effect.invisibility": "item.minecraft.tipped_arrow.effect.invisibility", + "tipped_arrow.effect.leaping": "item.minecraft.tipped_arrow.effect.leaping", + "tipped_arrow.effect.fire_resistance": "item.minecraft.tipped_arrow.effect.fire_resistance", + "tipped_arrow.effect.swiftness": "item.minecraft.tipped_arrow.effect.swiftness", + "tipped_arrow.effect.slowness": "item.minecraft.tipped_arrow.effect.slowness", + "tipped_arrow.effect.water_breathing": "item.minecraft.tipped_arrow.effect.water_breathing", + "tipped_arrow.effect.healing": "item.minecraft.tipped_arrow.effect.healing", + "tipped_arrow.effect.harming": "item.minecraft.tipped_arrow.effect.harming", + "tipped_arrow.effect.poison": "item.minecraft.tipped_arrow.effect.poison", + "tipped_arrow.effect.regeneration": "item.minecraft.tipped_arrow.effect.regeneration", + "tipped_arrow.effect.strength": "item.minecraft.tipped_arrow.effect.strength", + "tipped_arrow.effect.weakness": "item.minecraft.tipped_arrow.effect.weakness", + "tipped_arrow.effect.levitation": "item.minecraft.tipped_arrow.effect.levitation", + "tipped_arrow.effect.luck": "item.minecraft.tipped_arrow.effect.luck", + "potion.effect.empty": "item.minecraft.potion.effect.empty", + "potion.effect.water": "item.minecraft.potion.effect.water", + "potion.effect.mundane": "item.minecraft.potion.effect.mundane", + "potion.effect.thick": "item.minecraft.potion.effect.thick", + "potion.effect.awkward": "item.minecraft.potion.effect.awkward", + "potion.effect.night_vision": "item.minecraft.potion.effect.night_vision", + "potion.effect.invisibility": "item.minecraft.potion.effect.invisibility", + "potion.effect.leaping": "item.minecraft.potion.effect.leaping", + "potion.effect.fire_resistance": "item.minecraft.potion.effect.fire_resistance", + "potion.effect.swiftness": "item.minecraft.potion.effect.swiftness", + "potion.effect.slowness": "item.minecraft.potion.effect.slowness", + "potion.effect.water_breathing": "item.minecraft.potion.effect.water_breathing", + "potion.effect.healing": "item.minecraft.potion.effect.healing", + "potion.effect.harming": "item.minecraft.potion.effect.harming", + "potion.effect.poison": "item.minecraft.potion.effect.poison", + "potion.effect.regeneration": "item.minecraft.potion.effect.regeneration", + "potion.effect.strength": "item.minecraft.potion.effect.strength", + "potion.effect.weakness": "item.minecraft.potion.effect.weakness", + "potion.effect.levitation": "item.minecraft.potion.effect.levitation", + "potion.effect.luck": "item.minecraft.potion.effect.luck", + "splash_potion.effect.empty": "item.minecraft.splash_potion.effect.empty", + "splash_potion.effect.water": "item.minecraft.splash_potion.effect.water", + "splash_potion.effect.mundane": "item.minecraft.splash_potion.effect.mundane", + "splash_potion.effect.thick": "item.minecraft.splash_potion.effect.thick", + "splash_potion.effect.awkward": "item.minecraft.splash_potion.effect.awkward", + "splash_potion.effect.night_vision": "item.minecraft.splash_potion.effect.night_vision", + "splash_potion.effect.invisibility": "item.minecraft.splash_potion.effect.invisibility", + "splash_potion.effect.leaping": "item.minecraft.splash_potion.effect.leaping", + "splash_potion.effect.fire_resistance": "item.minecraft.splash_potion.effect.fire_resistance", + "splash_potion.effect.swiftness": "item.minecraft.splash_potion.effect.swiftness", + "splash_potion.effect.slowness": "item.minecraft.splash_potion.effect.slowness", + "splash_potion.effect.water_breathing": "item.minecraft.splash_potion.effect.water_breathing", + "splash_potion.effect.healing": "item.minecraft.splash_potion.effect.healing", + "splash_potion.effect.harming": "item.minecraft.splash_potion.effect.harming", + "splash_potion.effect.poison": "item.minecraft.splash_potion.effect.poison", + "splash_potion.effect.regeneration": "item.minecraft.splash_potion.effect.regeneration", + "splash_potion.effect.strength": "item.minecraft.splash_potion.effect.strength", + "splash_potion.effect.weakness": "item.minecraft.splash_potion.effect.weakness", + "splash_potion.effect.levitation": "item.minecraft.splash_potion.effect.levitation", + "splash_potion.effect.luck": "item.minecraft.splash_potion.effect.luck", + "lingering_potion.effect.empty": "item.minecraft.lingering_potion.effect.empty", + "lingering_potion.effect.water": "item.minecraft.lingering_potion.effect.water", + "lingering_potion.effect.mundane": "item.minecraft.lingering_potion.effect.mundane", + "lingering_potion.effect.thick": "item.minecraft.lingering_potion.effect.thick", + "lingering_potion.effect.awkward": "item.minecraft.lingering_potion.effect.awkward", + "lingering_potion.effect.night_vision": "item.minecraft.lingering_potion.effect.night_vision", + "lingering_potion.effect.invisibility": "item.minecraft.lingering_potion.effect.invisibility", + "lingering_potion.effect.leaping": "item.minecraft.lingering_potion.effect.leaping", + "lingering_potion.effect.fire_resistance": "item.minecraft.lingering_potion.effect.fire_resistance", + "lingering_potion.effect.swiftness": "item.minecraft.lingering_potion.effect.swiftness", + "lingering_potion.effect.slowness": "item.minecraft.lingering_potion.effect.slowness", + "lingering_potion.effect.water_breathing": "item.minecraft.lingering_potion.effect.water_breathing", + "lingering_potion.effect.healing": "item.minecraft.lingering_potion.effect.healing", + "lingering_potion.effect.harming": "item.minecraft.lingering_potion.effect.harming", + "lingering_potion.effect.poison": "item.minecraft.lingering_potion.effect.poison", + "lingering_potion.effect.regeneration": "item.minecraft.lingering_potion.effect.regeneration", + "lingering_potion.effect.strength": "item.minecraft.lingering_potion.effect.strength", + "lingering_potion.effect.weakness": "item.minecraft.lingering_potion.effect.weakness", + "lingering_potion.effect.levitation": "item.minecraft.lingering_potion.effect.levitation", + "lingering_potion.effect.luck": "item.minecraft.lingering_potion.effect.luck", + "potion.potency.0": "selectWorld.gameMode.spectator.line2", + "enchantment.damage.all": "enchantment.minecraft.sharpness", + "enchantment.damage.undead": "enchantment.minecraft.smite", + "enchantment.damage.arthropods": "enchantment.minecraft.bane_of_arthropods", + "enchantment.knockback": "enchantment.minecraft.knockback", + "enchantment.fire": "enchantment.minecraft.fire_aspect", + "enchantment.sweeping": "enchantment.minecraft.sweeping", + "enchantment.protect.all": "enchantment.minecraft.protection", + "enchantment.protect.fire": "enchantment.minecraft.fire_protection", + "enchantment.protect.fall": "enchantment.minecraft.feather_falling", + "enchantment.protect.explosion": "enchantment.minecraft.blast_protection", + "enchantment.protect.projectile": "enchantment.minecraft.projectile_protection", + "enchantment.oxygen": "enchantment.minecraft.respiration", + "enchantment.waterWorker": "enchantment.minecraft.aqua_affinity", + "enchantment.waterWalker": "enchantment.minecraft.depth_strider", + "enchantment.frostWalker": "enchantment.minecraft.frost_walker", + "enchantment.digging": "enchantment.minecraft.efficiency", + "enchantment.untouching": "enchantment.minecraft.silk_touch", + "enchantment.durability": "enchantment.minecraft.unbreaking", + "enchantment.lootBonus": "enchantment.minecraft.looting", + "enchantment.lootBonusDigger": "enchantment.minecraft.fortune", + "enchantment.lootBonusFishing": "enchantment.minecraft.luck_of_the_sea", + "enchantment.fishingSpeed": "enchantment.minecraft.lure", + "enchantment.arrowDamage": "enchantment.minecraft.power", + "enchantment.arrowFire": "enchantment.minecraft.flame", + "enchantment.arrowKnockback": "enchantment.minecraft.punch", + "enchantment.arrowInfinite": "enchantment.minecraft.infinity", + "enchantment.thorns": "enchantment.minecraft.thorns", + "enchantment.mending": "enchantment.minecraft.mending", + "enchantment.binding_curse": "enchantment.minecraft.binding_curse", + "enchantment.vanishing_curse": "enchantment.minecraft.vanishing_curse", + "enchantment.level.2": "potion.potency.1", + "enchantment.level.3": "potion.potency.2", + "enchantment.level.4": "potion.potency.3", + "enchantment.level.5": "potion.potency.4", + "enchantment.level.6": "potion.potency.5", + "gui.advancements": "key.advancements", + "stat.blocksButton": "soundCategory.block", + "stat.used": "stat_type.minecraft.used", + "stat.mined": "stat_type.minecraft.mined", + "stat.crafted": "stat_type.minecraft.crafted", + "stat.entityKills": "stat_type.minecraft.killed", + "stat.entityKilledBy": "stat_type.minecraft.killed_by", + "stat.entityKills.none": "stat_type.minecraft.killed.none", + "stat.entityKilledBy.none": "stat_type.minecraft.killed_by.none", + "stat.leaveGame": "stat.minecraft.leave_game", + "stat.playOneMinute": "stat.minecraft.play_one_minute", + "stat.timeSinceDeath": "stat.minecraft.time_since_death", + "stat.sneakTime": "stat.minecraft.sneak_time", + "stat.walkOneCm": "stat.minecraft.walk_one_cm", + "stat.crouchOneCm": "stat.minecraft.crouch_one_cm", + "stat.sprintOneCm": "stat.minecraft.sprint_one_cm", + "stat.fallOneCm": "stat.minecraft.fall_one_cm", + "stat.swimOneCm": "stat.minecraft.swim_one_cm", + "stat.flyOneCm": "stat.minecraft.fly_one_cm", + "stat.climbOneCm": "stat.minecraft.climb_one_cm", + "stat.minecartOneCm": "stat.minecraft.minecart_one_cm", + "stat.boatOneCm": "stat.minecraft.boat_one_cm", + "stat.pigOneCm": "stat.minecraft.pig_one_cm", + "stat.horseOneCm": "stat.minecraft.horse_one_cm", + "stat.aviateOneCm": "stat.minecraft.aviate_one_cm", + "stat.jump": "stat.minecraft.jump", + "stat.drop": "stat.minecraft.drop", + "stat.dropped": "stat_type.minecraft.dropped", + "stat.pickup": "stat_type.minecraft.picked_up", + "stat.damageDealt": "stat.minecraft.damage_dealt", + "stat.damageTaken": "stat.minecraft.damage_taken", + "stat.deaths": "stat.minecraft.deaths", + "stat.mobKills": "stat.minecraft.mob_kills", + "stat.animalsBred": "stat.minecraft.animals_bred", + "stat.playerKills": "stat.minecraft.player_kills", + "stat.fishCaught": "stat.minecraft.fish_caught", + "stat.treasureFished": "stat.minecraft.treasure_fished", + "stat.junkFished": "stat.minecraft.junk_fished", + "stat.talkedToVillager": "stat.minecraft.talked_to_villager", + "stat.tradedWithVillager": "stat.minecraft.traded_with_villager", + "stat.cakeSlicesEaten": "stat.minecraft.eat_cake_slice", + "stat.cauldronFilled": "stat.minecraft.fill_cauldron", + "stat.cauldronUsed": "stat.minecraft.use_cauldron", + "stat.armorCleaned": "stat.minecraft.clean_armor", + "stat.bannerCleaned": "stat.minecraft.clean_banner", + "stat.brewingstandInteraction": "stat.minecraft.interact_with_brewingstand", + "stat.beaconInteraction": "stat.minecraft.interact_with_beacon", + "stat.dropperInspected": "stat.minecraft.inspect_dropper", + "stat.hopperInspected": "stat.minecraft.inspect_hopper", + "stat.dispenserInspected": "stat.minecraft.inspect_dispenser", + "stat.noteblockPlayed": "stat.minecraft.play_noteblock", + "stat.noteblockTuned": "stat.minecraft.tune_noteblock", + "stat.flowerPotted": "stat.minecraft.pot_flower", + "stat.trappedChestTriggered": "stat.minecraft.trigger_trapped_chest", + "stat.enderchestOpened": "stat.minecraft.open_enderchest", + "stat.itemEnchanted": "stat.minecraft.enchant_item", + "stat.furnaceInteraction": "stat.minecraft.interact_with_furnace", + "stat.workbenchInteraction": "stat.minecraft.interact_with_crafting_table", + "stat.chestOpened": "stat.minecraft.open_chest", + "stat.shulkerBoxOpened": "stat.minecraft.open_shulker_box", + "stat.sleepInBed": "stat.minecraft.sleep_in_bed", + "commands.setblock.success": "subtitles.block.generic.place", + "commands.kill.successful": "commands.kill.success.single", + "commands.save-on.alreadyOn": "commands.save.alreadyOn", + "commands.save-off.alreadyOff": "commands.save.alreadyOff", + "commands.stop.start": "commands.stop.stopping", + "commands.tp.success": "commands.teleport.success.entity.single", + "commands.tp.success.coordinates": "commands.teleport.success.location.single", + "commands.teleport.success.coordinates": "commands.teleport.success.location.single", + "commands.scoreboard.players.enable.success": "commands.scoreboard.players.enable.success.single", + "commands.scoreboard.teams.remove.success": "commands.team.remove.success", + "commands.debug.start": "commands.debug.started", + "itemGroup.redstone": "item.minecraft.redstone", + "itemGroup.misc": "key.categories.misc", + "attribute.modifier.plus.2": "attribute.modifier.plus.1", + "attribute.modifier.take.2": "attribute.modifier.take.1", + "attribute.modifier.equals.0": "translation.test.args", + "attribute.modifier.equals.2": "attribute.modifier.equals.1", + "attribute.name.generic.movementSpeed": "effect.minecraft.speed", + "attribute.name.generic.luck": "effect.minecraft.luck", + "item.banner.black.name": "block.minecraft.black_banner", + "item.banner.red.name": "block.minecraft.red_banner", + "item.banner.green.name": "block.minecraft.green_banner", + "item.banner.brown.name": "block.minecraft.brown_banner", + "item.banner.blue.name": "block.minecraft.blue_banner", + "item.banner.purple.name": "block.minecraft.purple_banner", + "item.banner.cyan.name": "block.minecraft.cyan_banner", + "item.banner.silver.name": "block.minecraft.light_gray_banner", + "item.banner.gray.name": "block.minecraft.gray_banner", + "item.banner.pink.name": "block.minecraft.pink_banner", + "item.banner.lime.name": "block.minecraft.lime_banner", + "item.banner.yellow.name": "block.minecraft.yellow_banner", + "item.banner.lightBlue.name": "block.minecraft.light_blue_banner", + "item.banner.magenta.name": "block.minecraft.magenta_banner", + "item.banner.orange.name": "block.minecraft.orange_banner", + "item.banner.white.name": "block.minecraft.white_banner", + "item.shield.name": "item.minecraft.shield", + "item.shield.black.name": "item.minecraft.shield.black", + "item.shield.red.name": "item.minecraft.shield.red", + "item.shield.green.name": "item.minecraft.shield.green", + "item.shield.brown.name": "item.minecraft.shield.brown", + "item.shield.blue.name": "item.minecraft.shield.blue", + "item.shield.purple.name": "item.minecraft.shield.purple", + "item.shield.cyan.name": "item.minecraft.shield.cyan", + "item.shield.silver.name": "item.minecraft.shield.light_gray", + "item.shield.gray.name": "item.minecraft.shield.gray", + "item.shield.pink.name": "item.minecraft.shield.pink", + "item.shield.lime.name": "item.minecraft.shield.lime", + "item.shield.yellow.name": "item.minecraft.shield.yellow", + "item.shield.lightBlue.name": "item.minecraft.shield.light_blue", + "item.shield.magenta.name": "item.minecraft.shield.magenta", + "item.shield.orange.name": "item.minecraft.shield.orange", + "item.shield.white.name": "item.minecraft.shield.white", + "item.banner.square_bottom_left.black": "block.minecraft.banner.square_bottom_left.black", + "item.banner.square_bottom_left.red": "block.minecraft.banner.square_bottom_left.red", + "item.banner.square_bottom_left.green": "block.minecraft.banner.square_bottom_left.green", + "item.banner.square_bottom_left.brown": "block.minecraft.banner.square_bottom_left.brown", + "item.banner.square_bottom_left.blue": "block.minecraft.banner.square_bottom_left.blue", + "item.banner.square_bottom_left.purple": "block.minecraft.banner.square_bottom_left.purple", + "item.banner.square_bottom_left.cyan": "block.minecraft.banner.square_bottom_left.cyan", + "item.banner.square_bottom_left.silver": "block.minecraft.banner.square_bottom_left.light_gray", + "item.banner.square_bottom_left.gray": "block.minecraft.banner.square_bottom_left.gray", + "item.banner.square_bottom_left.pink": "block.minecraft.banner.square_bottom_left.pink", + "item.banner.square_bottom_left.lime": "block.minecraft.banner.square_bottom_left.lime", + "item.banner.square_bottom_left.yellow": "block.minecraft.banner.square_bottom_left.yellow", + "item.banner.square_bottom_left.lightBlue": "block.minecraft.banner.square_bottom_left.light_blue", + "item.banner.square_bottom_left.magenta": "block.minecraft.banner.square_bottom_left.magenta", + "item.banner.square_bottom_left.orange": "block.minecraft.banner.square_bottom_left.orange", + "item.banner.square_bottom_left.white": "block.minecraft.banner.square_bottom_left.white", + "item.banner.square_bottom_right.black": "block.minecraft.banner.square_bottom_right.black", + "item.banner.square_bottom_right.red": "block.minecraft.banner.square_bottom_right.red", + "item.banner.square_bottom_right.green": "block.minecraft.banner.square_bottom_right.green", + "item.banner.square_bottom_right.brown": "block.minecraft.banner.square_bottom_right.brown", + "item.banner.square_bottom_right.blue": "block.minecraft.banner.square_bottom_right.blue", + "item.banner.square_bottom_right.purple": "block.minecraft.banner.square_bottom_right.purple", + "item.banner.square_bottom_right.cyan": "block.minecraft.banner.square_bottom_right.cyan", + "item.banner.square_bottom_right.silver": "block.minecraft.banner.square_bottom_right.light_gray", + "item.banner.square_bottom_right.gray": "block.minecraft.banner.square_bottom_right.gray", + "item.banner.square_bottom_right.pink": "block.minecraft.banner.square_bottom_right.pink", + "item.banner.square_bottom_right.lime": "block.minecraft.banner.square_bottom_right.lime", + "item.banner.square_bottom_right.yellow": "block.minecraft.banner.square_bottom_right.yellow", + "item.banner.square_bottom_right.lightBlue": "block.minecraft.banner.square_bottom_right.light_blue", + "item.banner.square_bottom_right.magenta": "block.minecraft.banner.square_bottom_right.magenta", + "item.banner.square_bottom_right.orange": "block.minecraft.banner.square_bottom_right.orange", + "item.banner.square_bottom_right.white": "block.minecraft.banner.square_bottom_right.white", + "item.banner.square_top_left.black": "block.minecraft.banner.square_top_left.black", + "item.banner.square_top_left.red": "block.minecraft.banner.square_top_left.red", + "item.banner.square_top_left.green": "block.minecraft.banner.square_top_left.green", + "item.banner.square_top_left.brown": "block.minecraft.banner.square_top_left.brown", + "item.banner.square_top_left.blue": "block.minecraft.banner.square_top_left.blue", + "item.banner.square_top_left.purple": "block.minecraft.banner.square_top_left.purple", + "item.banner.square_top_left.cyan": "block.minecraft.banner.square_top_left.cyan", + "item.banner.square_top_left.silver": "block.minecraft.banner.square_top_left.light_gray", + "item.banner.square_top_left.gray": "block.minecraft.banner.square_top_left.gray", + "item.banner.square_top_left.pink": "block.minecraft.banner.square_top_left.pink", + "item.banner.square_top_left.lime": "block.minecraft.banner.square_top_left.lime", + "item.banner.square_top_left.yellow": "block.minecraft.banner.square_top_left.yellow", + "item.banner.square_top_left.lightBlue": "block.minecraft.banner.square_top_left.light_blue", + "item.banner.square_top_left.magenta": "block.minecraft.banner.square_top_left.magenta", + "item.banner.square_top_left.orange": "block.minecraft.banner.square_top_left.orange", + "item.banner.square_top_left.white": "block.minecraft.banner.square_top_left.white", + "item.banner.square_top_right.black": "block.minecraft.banner.square_top_right.black", + "item.banner.square_top_right.red": "block.minecraft.banner.square_top_right.red", + "item.banner.square_top_right.green": "block.minecraft.banner.square_top_right.green", + "item.banner.square_top_right.brown": "block.minecraft.banner.square_top_right.brown", + "item.banner.square_top_right.blue": "block.minecraft.banner.square_top_right.blue", + "item.banner.square_top_right.purple": "block.minecraft.banner.square_top_right.purple", + "item.banner.square_top_right.cyan": "block.minecraft.banner.square_top_right.cyan", + "item.banner.square_top_right.silver": "block.minecraft.banner.square_top_right.light_gray", + "item.banner.square_top_right.gray": "block.minecraft.banner.square_top_right.gray", + "item.banner.square_top_right.pink": "block.minecraft.banner.square_top_right.pink", + "item.banner.square_top_right.lime": "block.minecraft.banner.square_top_right.lime", + "item.banner.square_top_right.yellow": "block.minecraft.banner.square_top_right.yellow", + "item.banner.square_top_right.lightBlue": "block.minecraft.banner.square_top_right.light_blue", + "item.banner.square_top_right.magenta": "block.minecraft.banner.square_top_right.magenta", + "item.banner.square_top_right.orange": "block.minecraft.banner.square_top_right.orange", + "item.banner.square_top_right.white": "block.minecraft.banner.square_top_right.white", + "item.banner.stripe_bottom.black": "block.minecraft.banner.stripe_bottom.black", + "item.banner.stripe_bottom.red": "block.minecraft.banner.stripe_bottom.red", + "item.banner.stripe_bottom.green": "block.minecraft.banner.stripe_bottom.green", + "item.banner.stripe_bottom.brown": "block.minecraft.banner.stripe_bottom.brown", + "item.banner.stripe_bottom.blue": "block.minecraft.banner.stripe_bottom.blue", + "item.banner.stripe_bottom.purple": "block.minecraft.banner.stripe_bottom.purple", + "item.banner.stripe_bottom.cyan": "block.minecraft.banner.stripe_bottom.cyan", + "item.banner.stripe_bottom.silver": "block.minecraft.banner.stripe_bottom.light_gray", + "item.banner.stripe_bottom.gray": "block.minecraft.banner.stripe_bottom.gray", + "item.banner.stripe_bottom.pink": "block.minecraft.banner.stripe_bottom.pink", + "item.banner.stripe_bottom.lime": "block.minecraft.banner.stripe_bottom.lime", + "item.banner.stripe_bottom.yellow": "block.minecraft.banner.stripe_bottom.yellow", + "item.banner.stripe_bottom.lightBlue": "block.minecraft.banner.stripe_bottom.light_blue", + "item.banner.stripe_bottom.magenta": "block.minecraft.banner.stripe_bottom.magenta", + "item.banner.stripe_bottom.orange": "block.minecraft.banner.stripe_bottom.orange", + "item.banner.stripe_bottom.white": "block.minecraft.banner.stripe_bottom.white", + "item.banner.stripe_top.black": "block.minecraft.banner.stripe_top.black", + "item.banner.stripe_top.red": "block.minecraft.banner.stripe_top.red", + "item.banner.stripe_top.green": "block.minecraft.banner.stripe_top.green", + "item.banner.stripe_top.brown": "block.minecraft.banner.stripe_top.brown", + "item.banner.stripe_top.blue": "block.minecraft.banner.stripe_top.blue", + "item.banner.stripe_top.purple": "block.minecraft.banner.stripe_top.purple", + "item.banner.stripe_top.cyan": "block.minecraft.banner.stripe_top.cyan", + "item.banner.stripe_top.silver": "block.minecraft.banner.stripe_top.light_gray", + "item.banner.stripe_top.gray": "block.minecraft.banner.stripe_top.gray", + "item.banner.stripe_top.pink": "block.minecraft.banner.stripe_top.pink", + "item.banner.stripe_top.lime": "block.minecraft.banner.stripe_top.lime", + "item.banner.stripe_top.yellow": "block.minecraft.banner.stripe_top.yellow", + "item.banner.stripe_top.lightBlue": "block.minecraft.banner.stripe_top.light_blue", + "item.banner.stripe_top.magenta": "block.minecraft.banner.stripe_top.magenta", + "item.banner.stripe_top.orange": "block.minecraft.banner.stripe_top.orange", + "item.banner.stripe_top.white": "block.minecraft.banner.stripe_top.white", + "item.banner.stripe_left.black": "block.minecraft.banner.stripe_left.black", + "item.banner.stripe_left.red": "block.minecraft.banner.stripe_left.red", + "item.banner.stripe_left.green": "block.minecraft.banner.stripe_left.green", + "item.banner.stripe_left.brown": "block.minecraft.banner.stripe_left.brown", + "item.banner.stripe_left.blue": "block.minecraft.banner.stripe_left.blue", + "item.banner.stripe_left.purple": "block.minecraft.banner.stripe_left.purple", + "item.banner.stripe_left.cyan": "block.minecraft.banner.stripe_left.cyan", + "item.banner.stripe_left.silver": "block.minecraft.banner.stripe_left.light_gray", + "item.banner.stripe_left.gray": "block.minecraft.banner.stripe_left.gray", + "item.banner.stripe_left.pink": "block.minecraft.banner.stripe_left.pink", + "item.banner.stripe_left.lime": "block.minecraft.banner.stripe_left.lime", + "item.banner.stripe_left.yellow": "block.minecraft.banner.stripe_left.yellow", + "item.banner.stripe_left.lightBlue": "block.minecraft.banner.stripe_left.light_blue", + "item.banner.stripe_left.magenta": "block.minecraft.banner.stripe_left.magenta", + "item.banner.stripe_left.orange": "block.minecraft.banner.stripe_left.orange", + "item.banner.stripe_left.white": "block.minecraft.banner.stripe_left.white", + "item.banner.stripe_right.black": "block.minecraft.banner.stripe_right.black", + "item.banner.stripe_right.red": "block.minecraft.banner.stripe_right.red", + "item.banner.stripe_right.green": "block.minecraft.banner.stripe_right.green", + "item.banner.stripe_right.brown": "block.minecraft.banner.stripe_right.brown", + "item.banner.stripe_right.blue": "block.minecraft.banner.stripe_right.blue", + "item.banner.stripe_right.purple": "block.minecraft.banner.stripe_right.purple", + "item.banner.stripe_right.cyan": "block.minecraft.banner.stripe_right.cyan", + "item.banner.stripe_right.silver": "block.minecraft.banner.stripe_right.light_gray", + "item.banner.stripe_right.gray": "block.minecraft.banner.stripe_right.gray", + "item.banner.stripe_right.pink": "block.minecraft.banner.stripe_right.pink", + "item.banner.stripe_right.lime": "block.minecraft.banner.stripe_right.lime", + "item.banner.stripe_right.yellow": "block.minecraft.banner.stripe_right.yellow", + "item.banner.stripe_right.lightBlue": "block.minecraft.banner.stripe_right.light_blue", + "item.banner.stripe_right.magenta": "block.minecraft.banner.stripe_right.magenta", + "item.banner.stripe_right.orange": "block.minecraft.banner.stripe_right.orange", + "item.banner.stripe_right.white": "block.minecraft.banner.stripe_right.white", + "item.banner.stripe_center.black": "block.minecraft.banner.stripe_center.black", + "item.banner.stripe_center.red": "block.minecraft.banner.stripe_center.red", + "item.banner.stripe_center.green": "block.minecraft.banner.stripe_center.green", + "item.banner.stripe_center.brown": "block.minecraft.banner.stripe_center.brown", + "item.banner.stripe_center.blue": "block.minecraft.banner.stripe_center.blue", + "item.banner.stripe_center.purple": "block.minecraft.banner.stripe_center.purple", + "item.banner.stripe_center.cyan": "block.minecraft.banner.stripe_center.cyan", + "item.banner.stripe_center.silver": "block.minecraft.banner.stripe_center.light_gray", + "item.banner.stripe_center.gray": "block.minecraft.banner.stripe_center.gray", + "item.banner.stripe_center.pink": "block.minecraft.banner.stripe_center.pink", + "item.banner.stripe_center.lime": "block.minecraft.banner.stripe_center.lime", + "item.banner.stripe_center.yellow": "block.minecraft.banner.stripe_center.yellow", + "item.banner.stripe_center.lightBlue": "block.minecraft.banner.stripe_center.light_blue", + "item.banner.stripe_center.magenta": "block.minecraft.banner.stripe_center.magenta", + "item.banner.stripe_center.orange": "block.minecraft.banner.stripe_center.orange", + "item.banner.stripe_center.white": "block.minecraft.banner.stripe_center.white", + "item.banner.stripe_middle.black": "block.minecraft.banner.stripe_middle.black", + "item.banner.stripe_middle.red": "block.minecraft.banner.stripe_middle.red", + "item.banner.stripe_middle.green": "block.minecraft.banner.stripe_middle.green", + "item.banner.stripe_middle.brown": "block.minecraft.banner.stripe_middle.brown", + "item.banner.stripe_middle.blue": "block.minecraft.banner.stripe_middle.blue", + "item.banner.stripe_middle.purple": "block.minecraft.banner.stripe_middle.purple", + "item.banner.stripe_middle.cyan": "block.minecraft.banner.stripe_middle.cyan", + "item.banner.stripe_middle.silver": "block.minecraft.banner.stripe_middle.light_gray", + "item.banner.stripe_middle.gray": "block.minecraft.banner.stripe_middle.gray", + "item.banner.stripe_middle.pink": "block.minecraft.banner.stripe_middle.pink", + "item.banner.stripe_middle.lime": "block.minecraft.banner.stripe_middle.lime", + "item.banner.stripe_middle.yellow": "block.minecraft.banner.stripe_middle.yellow", + "item.banner.stripe_middle.lightBlue": "block.minecraft.banner.stripe_middle.light_blue", + "item.banner.stripe_middle.magenta": "block.minecraft.banner.stripe_middle.magenta", + "item.banner.stripe_middle.orange": "block.minecraft.banner.stripe_middle.orange", + "item.banner.stripe_middle.white": "block.minecraft.banner.stripe_middle.white", + "item.banner.stripe_downright.black": "block.minecraft.banner.stripe_downright.black", + "item.banner.stripe_downright.red": "block.minecraft.banner.stripe_downright.red", + "item.banner.stripe_downright.green": "block.minecraft.banner.stripe_downright.green", + "item.banner.stripe_downright.brown": "block.minecraft.banner.stripe_downright.brown", + "item.banner.stripe_downright.blue": "block.minecraft.banner.stripe_downright.blue", + "item.banner.stripe_downright.purple": "block.minecraft.banner.stripe_downright.purple", + "item.banner.stripe_downright.cyan": "block.minecraft.banner.stripe_downright.cyan", + "item.banner.stripe_downright.silver": "block.minecraft.banner.stripe_downright.light_gray", + "item.banner.stripe_downright.gray": "block.minecraft.banner.stripe_downright.gray", + "item.banner.stripe_downright.pink": "block.minecraft.banner.stripe_downright.pink", + "item.banner.stripe_downright.lime": "block.minecraft.banner.stripe_downright.lime", + "item.banner.stripe_downright.yellow": "block.minecraft.banner.stripe_downright.yellow", + "item.banner.stripe_downright.lightBlue": "block.minecraft.banner.stripe_downright.light_blue", + "item.banner.stripe_downright.magenta": "block.minecraft.banner.stripe_downright.magenta", + "item.banner.stripe_downright.orange": "block.minecraft.banner.stripe_downright.orange", + "item.banner.stripe_downright.white": "block.minecraft.banner.stripe_downright.white", + "item.banner.stripe_downleft.black": "block.minecraft.banner.stripe_downleft.black", + "item.banner.stripe_downleft.red": "block.minecraft.banner.stripe_downleft.red", + "item.banner.stripe_downleft.green": "block.minecraft.banner.stripe_downleft.green", + "item.banner.stripe_downleft.brown": "block.minecraft.banner.stripe_downleft.brown", + "item.banner.stripe_downleft.blue": "block.minecraft.banner.stripe_downleft.blue", + "item.banner.stripe_downleft.purple": "block.minecraft.banner.stripe_downleft.purple", + "item.banner.stripe_downleft.cyan": "block.minecraft.banner.stripe_downleft.cyan", + "item.banner.stripe_downleft.silver": "block.minecraft.banner.stripe_downleft.light_gray", + "item.banner.stripe_downleft.gray": "block.minecraft.banner.stripe_downleft.gray", + "item.banner.stripe_downleft.pink": "block.minecraft.banner.stripe_downleft.pink", + "item.banner.stripe_downleft.lime": "block.minecraft.banner.stripe_downleft.lime", + "item.banner.stripe_downleft.yellow": "block.minecraft.banner.stripe_downleft.yellow", + "item.banner.stripe_downleft.lightBlue": "block.minecraft.banner.stripe_downleft.light_blue", + "item.banner.stripe_downleft.magenta": "block.minecraft.banner.stripe_downleft.magenta", + "item.banner.stripe_downleft.orange": "block.minecraft.banner.stripe_downleft.orange", + "item.banner.stripe_downleft.white": "block.minecraft.banner.stripe_downleft.white", + "item.banner.small_stripes.black": "block.minecraft.banner.small_stripes.black", + "item.banner.small_stripes.red": "block.minecraft.banner.small_stripes.red", + "item.banner.small_stripes.green": "block.minecraft.banner.small_stripes.green", + "item.banner.small_stripes.brown": "block.minecraft.banner.small_stripes.brown", + "item.banner.small_stripes.blue": "block.minecraft.banner.small_stripes.blue", + "item.banner.small_stripes.purple": "block.minecraft.banner.small_stripes.purple", + "item.banner.small_stripes.cyan": "block.minecraft.banner.small_stripes.cyan", + "item.banner.small_stripes.silver": "block.minecraft.banner.small_stripes.light_gray", + "item.banner.small_stripes.gray": "block.minecraft.banner.small_stripes.gray", + "item.banner.small_stripes.pink": "block.minecraft.banner.small_stripes.pink", + "item.banner.small_stripes.lime": "block.minecraft.banner.small_stripes.lime", + "item.banner.small_stripes.yellow": "block.minecraft.banner.small_stripes.yellow", + "item.banner.small_stripes.lightBlue": "block.minecraft.banner.small_stripes.light_blue", + "item.banner.small_stripes.magenta": "block.minecraft.banner.small_stripes.magenta", + "item.banner.small_stripes.orange": "block.minecraft.banner.small_stripes.orange", + "item.banner.small_stripes.white": "block.minecraft.banner.small_stripes.white", + "item.banner.cross.black": "block.minecraft.banner.cross.black", + "item.banner.cross.red": "block.minecraft.banner.cross.red", + "item.banner.cross.green": "block.minecraft.banner.cross.green", + "item.banner.cross.brown": "block.minecraft.banner.cross.brown", + "item.banner.cross.blue": "block.minecraft.banner.cross.blue", + "item.banner.cross.purple": "block.minecraft.banner.cross.purple", + "item.banner.cross.cyan": "block.minecraft.banner.cross.cyan", + "item.banner.cross.silver": "block.minecraft.banner.cross.light_gray", + "item.banner.cross.gray": "block.minecraft.banner.cross.gray", + "item.banner.cross.pink": "block.minecraft.banner.cross.pink", + "item.banner.cross.lime": "block.minecraft.banner.cross.lime", + "item.banner.cross.yellow": "block.minecraft.banner.cross.yellow", + "item.banner.cross.lightBlue": "block.minecraft.banner.cross.light_blue", + "item.banner.cross.magenta": "block.minecraft.banner.cross.magenta", + "item.banner.cross.orange": "block.minecraft.banner.cross.orange", + "item.banner.cross.white": "block.minecraft.banner.cross.white", + "item.banner.triangle_bottom.black": "block.minecraft.banner.triangle_bottom.black", + "item.banner.triangle_bottom.red": "block.minecraft.banner.triangle_bottom.red", + "item.banner.triangle_bottom.green": "block.minecraft.banner.triangle_bottom.green", + "item.banner.triangle_bottom.brown": "block.minecraft.banner.triangle_bottom.brown", + "item.banner.triangle_bottom.blue": "block.minecraft.banner.triangle_bottom.blue", + "item.banner.triangle_bottom.purple": "block.minecraft.banner.triangle_bottom.purple", + "item.banner.triangle_bottom.cyan": "block.minecraft.banner.triangle_bottom.cyan", + "item.banner.triangle_bottom.silver": "block.minecraft.banner.triangle_bottom.light_gray", + "item.banner.triangle_bottom.gray": "block.minecraft.banner.triangle_bottom.gray", + "item.banner.triangle_bottom.pink": "block.minecraft.banner.triangle_bottom.pink", + "item.banner.triangle_bottom.lime": "block.minecraft.banner.triangle_bottom.lime", + "item.banner.triangle_bottom.yellow": "block.minecraft.banner.triangle_bottom.yellow", + "item.banner.triangle_bottom.lightBlue": "block.minecraft.banner.triangle_bottom.light_blue", + "item.banner.triangle_bottom.magenta": "block.minecraft.banner.triangle_bottom.magenta", + "item.banner.triangle_bottom.orange": "block.minecraft.banner.triangle_bottom.orange", + "item.banner.triangle_bottom.white": "block.minecraft.banner.triangle_bottom.white", + "item.banner.triangle_top.black": "block.minecraft.banner.triangle_top.black", + "item.banner.triangle_top.red": "block.minecraft.banner.triangle_top.red", + "item.banner.triangle_top.green": "block.minecraft.banner.triangle_top.green", + "item.banner.triangle_top.brown": "block.minecraft.banner.triangle_top.brown", + "item.banner.triangle_top.blue": "block.minecraft.banner.triangle_top.blue", + "item.banner.triangle_top.purple": "block.minecraft.banner.triangle_top.purple", + "item.banner.triangle_top.cyan": "block.minecraft.banner.triangle_top.cyan", + "item.banner.triangle_top.silver": "block.minecraft.banner.triangle_top.light_gray", + "item.banner.triangle_top.gray": "block.minecraft.banner.triangle_top.gray", + "item.banner.triangle_top.pink": "block.minecraft.banner.triangle_top.pink", + "item.banner.triangle_top.lime": "block.minecraft.banner.triangle_top.lime", + "item.banner.triangle_top.yellow": "block.minecraft.banner.triangle_top.yellow", + "item.banner.triangle_top.lightBlue": "block.minecraft.banner.triangle_top.light_blue", + "item.banner.triangle_top.magenta": "block.minecraft.banner.triangle_top.magenta", + "item.banner.triangle_top.orange": "block.minecraft.banner.triangle_top.orange", + "item.banner.triangle_top.white": "block.minecraft.banner.triangle_top.white", + "item.banner.triangles_bottom.black": "block.minecraft.banner.triangles_bottom.black", + "item.banner.triangles_bottom.red": "block.minecraft.banner.triangles_bottom.red", + "item.banner.triangles_bottom.green": "block.minecraft.banner.triangles_bottom.green", + "item.banner.triangles_bottom.brown": "block.minecraft.banner.triangles_bottom.brown", + "item.banner.triangles_bottom.blue": "block.minecraft.banner.triangles_bottom.blue", + "item.banner.triangles_bottom.purple": "block.minecraft.banner.triangles_bottom.purple", + "item.banner.triangles_bottom.cyan": "block.minecraft.banner.triangles_bottom.cyan", + "item.banner.triangles_bottom.silver": "block.minecraft.banner.triangles_bottom.light_gray", + "item.banner.triangles_bottom.gray": "block.minecraft.banner.triangles_bottom.gray", + "item.banner.triangles_bottom.pink": "block.minecraft.banner.triangles_bottom.pink", + "item.banner.triangles_bottom.lime": "block.minecraft.banner.triangles_bottom.lime", + "item.banner.triangles_bottom.yellow": "block.minecraft.banner.triangles_bottom.yellow", + "item.banner.triangles_bottom.lightBlue": "block.minecraft.banner.triangles_bottom.light_blue", + "item.banner.triangles_bottom.magenta": "block.minecraft.banner.triangles_bottom.magenta", + "item.banner.triangles_bottom.orange": "block.minecraft.banner.triangles_bottom.orange", + "item.banner.triangles_bottom.white": "block.minecraft.banner.triangles_bottom.white", + "item.banner.triangles_top.black": "block.minecraft.banner.triangles_top.black", + "item.banner.triangles_top.red": "block.minecraft.banner.triangles_top.red", + "item.banner.triangles_top.green": "block.minecraft.banner.triangles_top.green", + "item.banner.triangles_top.brown": "block.minecraft.banner.triangles_top.brown", + "item.banner.triangles_top.blue": "block.minecraft.banner.triangles_top.blue", + "item.banner.triangles_top.purple": "block.minecraft.banner.triangles_top.purple", + "item.banner.triangles_top.cyan": "block.minecraft.banner.triangles_top.cyan", + "item.banner.triangles_top.silver": "block.minecraft.banner.triangles_top.light_gray", + "item.banner.triangles_top.gray": "block.minecraft.banner.triangles_top.gray", + "item.banner.triangles_top.pink": "block.minecraft.banner.triangles_top.pink", + "item.banner.triangles_top.lime": "block.minecraft.banner.triangles_top.lime", + "item.banner.triangles_top.yellow": "block.minecraft.banner.triangles_top.yellow", + "item.banner.triangles_top.lightBlue": "block.minecraft.banner.triangles_top.light_blue", + "item.banner.triangles_top.magenta": "block.minecraft.banner.triangles_top.magenta", + "item.banner.triangles_top.orange": "block.minecraft.banner.triangles_top.orange", + "item.banner.triangles_top.white": "block.minecraft.banner.triangles_top.white", + "item.banner.diagonal_left.black": "block.minecraft.banner.diagonal_left.black", + "item.banner.diagonal_left.red": "block.minecraft.banner.diagonal_left.red", + "item.banner.diagonal_left.green": "block.minecraft.banner.diagonal_left.green", + "item.banner.diagonal_left.brown": "block.minecraft.banner.diagonal_left.brown", + "item.banner.diagonal_left.blue": "block.minecraft.banner.diagonal_left.blue", + "item.banner.diagonal_left.purple": "block.minecraft.banner.diagonal_left.purple", + "item.banner.diagonal_left.cyan": "block.minecraft.banner.diagonal_left.cyan", + "item.banner.diagonal_left.silver": "block.minecraft.banner.diagonal_left.light_gray", + "item.banner.diagonal_left.gray": "block.minecraft.banner.diagonal_left.gray", + "item.banner.diagonal_left.pink": "block.minecraft.banner.diagonal_left.pink", + "item.banner.diagonal_left.lime": "block.minecraft.banner.diagonal_left.lime", + "item.banner.diagonal_left.yellow": "block.minecraft.banner.diagonal_left.yellow", + "item.banner.diagonal_left.lightBlue": "block.minecraft.banner.diagonal_left.light_blue", + "item.banner.diagonal_left.magenta": "block.minecraft.banner.diagonal_left.magenta", + "item.banner.diagonal_left.orange": "block.minecraft.banner.diagonal_left.orange", + "item.banner.diagonal_left.white": "block.minecraft.banner.diagonal_left.white", + "item.banner.diagonal_right.black": "block.minecraft.banner.diagonal_right.black", + "item.banner.diagonal_right.red": "block.minecraft.banner.diagonal_right.red", + "item.banner.diagonal_right.green": "block.minecraft.banner.diagonal_right.green", + "item.banner.diagonal_right.brown": "block.minecraft.banner.diagonal_right.brown", + "item.banner.diagonal_right.blue": "block.minecraft.banner.diagonal_right.blue", + "item.banner.diagonal_right.purple": "block.minecraft.banner.diagonal_right.purple", + "item.banner.diagonal_right.cyan": "block.minecraft.banner.diagonal_right.cyan", + "item.banner.diagonal_right.silver": "block.minecraft.banner.diagonal_right.light_gray", + "item.banner.diagonal_right.gray": "block.minecraft.banner.diagonal_right.gray", + "item.banner.diagonal_right.pink": "block.minecraft.banner.diagonal_right.pink", + "item.banner.diagonal_right.lime": "block.minecraft.banner.diagonal_right.lime", + "item.banner.diagonal_right.yellow": "block.minecraft.banner.diagonal_right.yellow", + "item.banner.diagonal_right.lightBlue": "block.minecraft.banner.diagonal_right.light_blue", + "item.banner.diagonal_right.magenta": "block.minecraft.banner.diagonal_right.magenta", + "item.banner.diagonal_right.orange": "block.minecraft.banner.diagonal_right.orange", + "item.banner.diagonal_right.white": "block.minecraft.banner.diagonal_right.white", + "item.banner.diagonal_up_left.black": "block.minecraft.banner.diagonal_up_left.black", + "item.banner.diagonal_up_left.red": "block.minecraft.banner.diagonal_up_left.red", + "item.banner.diagonal_up_left.green": "block.minecraft.banner.diagonal_up_left.green", + "item.banner.diagonal_up_left.brown": "block.minecraft.banner.diagonal_up_left.brown", + "item.banner.diagonal_up_left.blue": "block.minecraft.banner.diagonal_up_left.blue", + "item.banner.diagonal_up_left.purple": "block.minecraft.banner.diagonal_up_left.purple", + "item.banner.diagonal_up_left.cyan": "block.minecraft.banner.diagonal_up_left.cyan", + "item.banner.diagonal_up_left.silver": "block.minecraft.banner.diagonal_up_left.light_gray", + "item.banner.diagonal_up_left.gray": "block.minecraft.banner.diagonal_up_left.gray", + "item.banner.diagonal_up_left.pink": "block.minecraft.banner.diagonal_up_left.pink", + "item.banner.diagonal_up_left.lime": "block.minecraft.banner.diagonal_up_left.lime", + "item.banner.diagonal_up_left.yellow": "block.minecraft.banner.diagonal_up_left.yellow", + "item.banner.diagonal_up_left.lightBlue": "block.minecraft.banner.diagonal_up_left.light_blue", + "item.banner.diagonal_up_left.magenta": "block.minecraft.banner.diagonal_up_left.magenta", + "item.banner.diagonal_up_left.orange": "block.minecraft.banner.diagonal_up_left.orange", + "item.banner.diagonal_up_left.white": "block.minecraft.banner.diagonal_up_left.white", + "item.banner.diagonal_up_right.black": "block.minecraft.banner.diagonal_up_right.black", + "item.banner.diagonal_up_right.red": "block.minecraft.banner.diagonal_up_right.red", + "item.banner.diagonal_up_right.green": "block.minecraft.banner.diagonal_up_right.green", + "item.banner.diagonal_up_right.brown": "block.minecraft.banner.diagonal_up_right.brown", + "item.banner.diagonal_up_right.blue": "block.minecraft.banner.diagonal_up_right.blue", + "item.banner.diagonal_up_right.purple": "block.minecraft.banner.diagonal_up_right.purple", + "item.banner.diagonal_up_right.cyan": "block.minecraft.banner.diagonal_up_right.cyan", + "item.banner.diagonal_up_right.silver": "block.minecraft.banner.diagonal_up_right.light_gray", + "item.banner.diagonal_up_right.gray": "block.minecraft.banner.diagonal_up_right.gray", + "item.banner.diagonal_up_right.pink": "block.minecraft.banner.diagonal_up_right.pink", + "item.banner.diagonal_up_right.lime": "block.minecraft.banner.diagonal_up_right.lime", + "item.banner.diagonal_up_right.yellow": "block.minecraft.banner.diagonal_up_right.yellow", + "item.banner.diagonal_up_right.lightBlue": "block.minecraft.banner.diagonal_up_right.light_blue", + "item.banner.diagonal_up_right.magenta": "block.minecraft.banner.diagonal_up_right.magenta", + "item.banner.diagonal_up_right.orange": "block.minecraft.banner.diagonal_up_right.orange", + "item.banner.diagonal_up_right.white": "block.minecraft.banner.diagonal_up_right.white", + "item.banner.circle.black": "block.minecraft.banner.circle.black", + "item.banner.circle.red": "block.minecraft.banner.circle.red", + "item.banner.circle.green": "block.minecraft.banner.circle.green", + "item.banner.circle.brown": "block.minecraft.banner.circle.brown", + "item.banner.circle.blue": "block.minecraft.banner.circle.blue", + "item.banner.circle.purple": "block.minecraft.banner.circle.purple", + "item.banner.circle.cyan": "block.minecraft.banner.circle.cyan", + "item.banner.circle.silver": "block.minecraft.banner.circle.light_gray", + "item.banner.circle.gray": "block.minecraft.banner.circle.gray", + "item.banner.circle.pink": "block.minecraft.banner.circle.pink", + "item.banner.circle.lime": "block.minecraft.banner.circle.lime", + "item.banner.circle.yellow": "block.minecraft.banner.circle.yellow", + "item.banner.circle.lightBlue": "block.minecraft.banner.circle.light_blue", + "item.banner.circle.magenta": "block.minecraft.banner.circle.magenta", + "item.banner.circle.orange": "block.minecraft.banner.circle.orange", + "item.banner.circle.white": "block.minecraft.banner.circle.white", + "item.banner.rhombus.black": "block.minecraft.banner.rhombus.black", + "item.banner.rhombus.red": "block.minecraft.banner.rhombus.red", + "item.banner.rhombus.green": "block.minecraft.banner.rhombus.green", + "item.banner.rhombus.brown": "block.minecraft.banner.rhombus.brown", + "item.banner.rhombus.blue": "block.minecraft.banner.rhombus.blue", + "item.banner.rhombus.purple": "block.minecraft.banner.rhombus.purple", + "item.banner.rhombus.cyan": "block.minecraft.banner.rhombus.cyan", + "item.banner.rhombus.silver": "block.minecraft.banner.rhombus.light_gray", + "item.banner.rhombus.gray": "block.minecraft.banner.rhombus.gray", + "item.banner.rhombus.pink": "block.minecraft.banner.rhombus.pink", + "item.banner.rhombus.lime": "block.minecraft.banner.rhombus.lime", + "item.banner.rhombus.yellow": "block.minecraft.banner.rhombus.yellow", + "item.banner.rhombus.lightBlue": "block.minecraft.banner.rhombus.light_blue", + "item.banner.rhombus.magenta": "block.minecraft.banner.rhombus.magenta", + "item.banner.rhombus.orange": "block.minecraft.banner.rhombus.orange", + "item.banner.rhombus.white": "block.minecraft.banner.rhombus.white", + "item.banner.half_vertical.black": "block.minecraft.banner.half_vertical.black", + "item.banner.half_vertical.red": "block.minecraft.banner.half_vertical.red", + "item.banner.half_vertical.green": "block.minecraft.banner.half_vertical.green", + "item.banner.half_vertical.brown": "block.minecraft.banner.half_vertical.brown", + "item.banner.half_vertical.blue": "block.minecraft.banner.half_vertical.blue", + "item.banner.half_vertical.purple": "block.minecraft.banner.half_vertical.purple", + "item.banner.half_vertical.cyan": "block.minecraft.banner.half_vertical.cyan", + "item.banner.half_vertical.silver": "block.minecraft.banner.half_vertical.light_gray", + "item.banner.half_vertical.gray": "block.minecraft.banner.half_vertical.gray", + "item.banner.half_vertical.pink": "block.minecraft.banner.half_vertical.pink", + "item.banner.half_vertical.lime": "block.minecraft.banner.half_vertical.lime", + "item.banner.half_vertical.yellow": "block.minecraft.banner.half_vertical.yellow", + "item.banner.half_vertical.lightBlue": "block.minecraft.banner.half_vertical.light_blue", + "item.banner.half_vertical.magenta": "block.minecraft.banner.half_vertical.magenta", + "item.banner.half_vertical.orange": "block.minecraft.banner.half_vertical.orange", + "item.banner.half_vertical.white": "block.minecraft.banner.half_vertical.white", + "item.banner.half_horizontal.black": "block.minecraft.banner.half_horizontal.black", + "item.banner.half_horizontal.red": "block.minecraft.banner.half_horizontal.red", + "item.banner.half_horizontal.green": "block.minecraft.banner.half_horizontal.green", + "item.banner.half_horizontal.brown": "block.minecraft.banner.half_horizontal.brown", + "item.banner.half_horizontal.blue": "block.minecraft.banner.half_horizontal.blue", + "item.banner.half_horizontal.purple": "block.minecraft.banner.half_horizontal.purple", + "item.banner.half_horizontal.cyan": "block.minecraft.banner.half_horizontal.cyan", + "item.banner.half_horizontal.silver": "block.minecraft.banner.half_horizontal.light_gray", + "item.banner.half_horizontal.gray": "block.minecraft.banner.half_horizontal.gray", + "item.banner.half_horizontal.pink": "block.minecraft.banner.half_horizontal.pink", + "item.banner.half_horizontal.lime": "block.minecraft.banner.half_horizontal.lime", + "item.banner.half_horizontal.yellow": "block.minecraft.banner.half_horizontal.yellow", + "item.banner.half_horizontal.lightBlue": "block.minecraft.banner.half_horizontal.light_blue", + "item.banner.half_horizontal.magenta": "block.minecraft.banner.half_horizontal.magenta", + "item.banner.half_horizontal.orange": "block.minecraft.banner.half_horizontal.orange", + "item.banner.half_horizontal.white": "block.minecraft.banner.half_horizontal.white", + "item.banner.half_vertical_right.black": "block.minecraft.banner.half_vertical_right.black", + "item.banner.half_vertical_right.red": "block.minecraft.banner.half_vertical_right.red", + "item.banner.half_vertical_right.green": "block.minecraft.banner.half_vertical_right.green", + "item.banner.half_vertical_right.brown": "block.minecraft.banner.half_vertical_right.brown", + "item.banner.half_vertical_right.blue": "block.minecraft.banner.half_vertical_right.blue", + "item.banner.half_vertical_right.purple": "block.minecraft.banner.half_vertical_right.purple", + "item.banner.half_vertical_right.cyan": "block.minecraft.banner.half_vertical_right.cyan", + "item.banner.half_vertical_right.silver": "block.minecraft.banner.half_vertical_right.light_gray", + "item.banner.half_vertical_right.gray": "block.minecraft.banner.half_vertical_right.gray", + "item.banner.half_vertical_right.pink": "block.minecraft.banner.half_vertical_right.pink", + "item.banner.half_vertical_right.lime": "block.minecraft.banner.half_vertical_right.lime", + "item.banner.half_vertical_right.yellow": "block.minecraft.banner.half_vertical_right.yellow", + "item.banner.half_vertical_right.lightBlue": "block.minecraft.banner.half_vertical_right.light_blue", + "item.banner.half_vertical_right.magenta": "block.minecraft.banner.half_vertical_right.magenta", + "item.banner.half_vertical_right.orange": "block.minecraft.banner.half_vertical_right.orange", + "item.banner.half_vertical_right.white": "block.minecraft.banner.half_vertical_right.white", + "item.banner.half_horizontal_bottom.black": "block.minecraft.banner.half_horizontal_bottom.black", + "item.banner.half_horizontal_bottom.red": "block.minecraft.banner.half_horizontal_bottom.red", + "item.banner.half_horizontal_bottom.green": "block.minecraft.banner.half_horizontal_bottom.green", + "item.banner.half_horizontal_bottom.brown": "block.minecraft.banner.half_horizontal_bottom.brown", + "item.banner.half_horizontal_bottom.blue": "block.minecraft.banner.half_horizontal_bottom.blue", + "item.banner.half_horizontal_bottom.purple": "block.minecraft.banner.half_horizontal_bottom.purple", + "item.banner.half_horizontal_bottom.cyan": "block.minecraft.banner.half_horizontal_bottom.cyan", + "item.banner.half_horizontal_bottom.silver": "block.minecraft.banner.half_horizontal_bottom.light_gray", + "item.banner.half_horizontal_bottom.gray": "block.minecraft.banner.half_horizontal_bottom.gray", + "item.banner.half_horizontal_bottom.pink": "block.minecraft.banner.half_horizontal_bottom.pink", + "item.banner.half_horizontal_bottom.lime": "block.minecraft.banner.half_horizontal_bottom.lime", + "item.banner.half_horizontal_bottom.yellow": "block.minecraft.banner.half_horizontal_bottom.yellow", + "item.banner.half_horizontal_bottom.lightBlue": "block.minecraft.banner.half_horizontal_bottom.light_blue", + "item.banner.half_horizontal_bottom.magenta": "block.minecraft.banner.half_horizontal_bottom.magenta", + "item.banner.half_horizontal_bottom.orange": "block.minecraft.banner.half_horizontal_bottom.orange", + "item.banner.half_horizontal_bottom.white": "block.minecraft.banner.half_horizontal_bottom.white", + "item.banner.creeper.black": "block.minecraft.banner.creeper.black", + "item.banner.creeper.red": "block.minecraft.banner.creeper.red", + "item.banner.creeper.green": "block.minecraft.banner.creeper.green", + "item.banner.creeper.brown": "block.minecraft.banner.creeper.brown", + "item.banner.creeper.blue": "block.minecraft.banner.creeper.blue", + "item.banner.creeper.purple": "block.minecraft.banner.creeper.purple", + "item.banner.creeper.cyan": "block.minecraft.banner.creeper.cyan", + "item.banner.creeper.silver": "block.minecraft.banner.creeper.light_gray", + "item.banner.creeper.gray": "block.minecraft.banner.creeper.gray", + "item.banner.creeper.pink": "block.minecraft.banner.creeper.pink", + "item.banner.creeper.lime": "block.minecraft.banner.creeper.lime", + "item.banner.creeper.yellow": "block.minecraft.banner.creeper.yellow", + "item.banner.creeper.lightBlue": "block.minecraft.banner.creeper.light_blue", + "item.banner.creeper.magenta": "block.minecraft.banner.creeper.magenta", + "item.banner.creeper.orange": "block.minecraft.banner.creeper.orange", + "item.banner.creeper.white": "block.minecraft.banner.creeper.white", + "item.banner.bricks.black": "block.minecraft.banner.bricks.black", + "item.banner.bricks.red": "block.minecraft.banner.bricks.red", + "item.banner.bricks.green": "block.minecraft.banner.bricks.green", + "item.banner.bricks.brown": "block.minecraft.banner.bricks.brown", + "item.banner.bricks.blue": "block.minecraft.banner.bricks.blue", + "item.banner.bricks.purple": "block.minecraft.banner.bricks.purple", + "item.banner.bricks.cyan": "block.minecraft.banner.bricks.cyan", + "item.banner.bricks.silver": "block.minecraft.banner.bricks.light_gray", + "item.banner.bricks.gray": "block.minecraft.banner.bricks.gray", + "item.banner.bricks.pink": "block.minecraft.banner.bricks.pink", + "item.banner.bricks.lime": "block.minecraft.banner.bricks.lime", + "item.banner.bricks.yellow": "block.minecraft.banner.bricks.yellow", + "item.banner.bricks.lightBlue": "block.minecraft.banner.bricks.light_blue", + "item.banner.bricks.magenta": "block.minecraft.banner.bricks.magenta", + "item.banner.bricks.orange": "block.minecraft.banner.bricks.orange", + "item.banner.bricks.white": "block.minecraft.banner.bricks.white", + "item.banner.gradient.black": "block.minecraft.banner.gradient.black", + "item.banner.gradient.red": "block.minecraft.banner.gradient.red", + "item.banner.gradient.green": "block.minecraft.banner.gradient.green", + "item.banner.gradient.brown": "block.minecraft.banner.gradient.brown", + "item.banner.gradient.blue": "block.minecraft.banner.gradient.blue", + "item.banner.gradient.purple": "block.minecraft.banner.gradient.purple", + "item.banner.gradient.cyan": "block.minecraft.banner.gradient.cyan", + "item.banner.gradient.silver": "block.minecraft.banner.gradient.light_gray", + "item.banner.gradient.gray": "block.minecraft.banner.gradient.gray", + "item.banner.gradient.pink": "block.minecraft.banner.gradient.pink", + "item.banner.gradient.lime": "block.minecraft.banner.gradient.lime", + "item.banner.gradient.yellow": "block.minecraft.banner.gradient.yellow", + "item.banner.gradient.lightBlue": "block.minecraft.banner.gradient.light_blue", + "item.banner.gradient.magenta": "block.minecraft.banner.gradient.magenta", + "item.banner.gradient.orange": "block.minecraft.banner.gradient.orange", + "item.banner.gradient.white": "block.minecraft.banner.gradient.white", + "item.banner.gradient_up.black": "block.minecraft.banner.gradient_up.black", + "item.banner.gradient_up.red": "block.minecraft.banner.gradient_up.red", + "item.banner.gradient_up.green": "block.minecraft.banner.gradient_up.green", + "item.banner.gradient_up.brown": "block.minecraft.banner.gradient_up.brown", + "item.banner.gradient_up.blue": "block.minecraft.banner.gradient_up.blue", + "item.banner.gradient_up.purple": "block.minecraft.banner.gradient_up.purple", + "item.banner.gradient_up.cyan": "block.minecraft.banner.gradient_up.cyan", + "item.banner.gradient_up.silver": "block.minecraft.banner.gradient_up.light_gray", + "item.banner.gradient_up.gray": "block.minecraft.banner.gradient_up.gray", + "item.banner.gradient_up.pink": "block.minecraft.banner.gradient_up.pink", + "item.banner.gradient_up.lime": "block.minecraft.banner.gradient_up.lime", + "item.banner.gradient_up.yellow": "block.minecraft.banner.gradient_up.yellow", + "item.banner.gradient_up.lightBlue": "block.minecraft.banner.gradient_up.light_blue", + "item.banner.gradient_up.magenta": "block.minecraft.banner.gradient_up.magenta", + "item.banner.gradient_up.orange": "block.minecraft.banner.gradient_up.orange", + "item.banner.gradient_up.white": "block.minecraft.banner.gradient_up.white", + "item.banner.skull.black": "block.minecraft.banner.skull.black", + "item.banner.skull.red": "block.minecraft.banner.skull.red", + "item.banner.skull.green": "block.minecraft.banner.skull.green", + "item.banner.skull.brown": "block.minecraft.banner.skull.brown", + "item.banner.skull.blue": "block.minecraft.banner.skull.blue", + "item.banner.skull.purple": "block.minecraft.banner.skull.purple", + "item.banner.skull.cyan": "block.minecraft.banner.skull.cyan", + "item.banner.skull.silver": "block.minecraft.banner.skull.light_gray", + "item.banner.skull.gray": "block.minecraft.banner.skull.gray", + "item.banner.skull.pink": "block.minecraft.banner.skull.pink", + "item.banner.skull.lime": "block.minecraft.banner.skull.lime", + "item.banner.skull.yellow": "block.minecraft.banner.skull.yellow", + "item.banner.skull.lightBlue": "block.minecraft.banner.skull.light_blue", + "item.banner.skull.magenta": "block.minecraft.banner.skull.magenta", + "item.banner.skull.orange": "block.minecraft.banner.skull.orange", + "item.banner.skull.white": "block.minecraft.banner.skull.white", + "item.banner.flower.black": "block.minecraft.banner.flower.black", + "item.banner.flower.red": "block.minecraft.banner.flower.red", + "item.banner.flower.green": "block.minecraft.banner.flower.green", + "item.banner.flower.brown": "block.minecraft.banner.flower.brown", + "item.banner.flower.blue": "block.minecraft.banner.flower.blue", + "item.banner.flower.purple": "block.minecraft.banner.flower.purple", + "item.banner.flower.cyan": "block.minecraft.banner.flower.cyan", + "item.banner.flower.silver": "block.minecraft.banner.flower.light_gray", + "item.banner.flower.gray": "block.minecraft.banner.flower.gray", + "item.banner.flower.pink": "block.minecraft.banner.flower.pink", + "item.banner.flower.lime": "block.minecraft.banner.flower.lime", + "item.banner.flower.yellow": "block.minecraft.banner.flower.yellow", + "item.banner.flower.lightBlue": "block.minecraft.banner.flower.light_blue", + "item.banner.flower.magenta": "block.minecraft.banner.flower.magenta", + "item.banner.flower.orange": "block.minecraft.banner.flower.orange", + "item.banner.flower.white": "block.minecraft.banner.flower.white", + "item.banner.border.black": "block.minecraft.banner.border.black", + "item.banner.border.red": "block.minecraft.banner.border.red", + "item.banner.border.green": "block.minecraft.banner.border.green", + "item.banner.border.brown": "block.minecraft.banner.border.brown", + "item.banner.border.blue": "block.minecraft.banner.border.blue", + "item.banner.border.purple": "block.minecraft.banner.border.purple", + "item.banner.border.cyan": "block.minecraft.banner.border.cyan", + "item.banner.border.silver": "block.minecraft.banner.border.light_gray", + "item.banner.border.gray": "block.minecraft.banner.border.gray", + "item.banner.border.pink": "block.minecraft.banner.border.pink", + "item.banner.border.lime": "block.minecraft.banner.border.lime", + "item.banner.border.yellow": "block.minecraft.banner.border.yellow", + "item.banner.border.lightBlue": "block.minecraft.banner.border.light_blue", + "item.banner.border.magenta": "block.minecraft.banner.border.magenta", + "item.banner.border.orange": "block.minecraft.banner.border.orange", + "item.banner.border.white": "block.minecraft.banner.border.white", + "item.banner.curly_border.black": "block.minecraft.banner.curly_border.black", + "item.banner.curly_border.red": "block.minecraft.banner.curly_border.red", + "item.banner.curly_border.green": "block.minecraft.banner.curly_border.green", + "item.banner.curly_border.brown": "block.minecraft.banner.curly_border.brown", + "item.banner.curly_border.blue": "block.minecraft.banner.curly_border.blue", + "item.banner.curly_border.purple": "block.minecraft.banner.curly_border.purple", + "item.banner.curly_border.cyan": "block.minecraft.banner.curly_border.cyan", + "item.banner.curly_border.silver": "block.minecraft.banner.curly_border.light_gray", + "item.banner.curly_border.gray": "block.minecraft.banner.curly_border.gray", + "item.banner.curly_border.pink": "block.minecraft.banner.curly_border.pink", + "item.banner.curly_border.lime": "block.minecraft.banner.curly_border.lime", + "item.banner.curly_border.yellow": "block.minecraft.banner.curly_border.yellow", + "item.banner.curly_border.lightBlue": "block.minecraft.banner.curly_border.light_blue", + "item.banner.curly_border.magenta": "block.minecraft.banner.curly_border.magenta", + "item.banner.curly_border.orange": "block.minecraft.banner.curly_border.orange", + "item.banner.curly_border.white": "block.minecraft.banner.curly_border.white", + "item.banner.mojang.black": "block.minecraft.banner.mojang.black", + "item.banner.mojang.red": "block.minecraft.banner.mojang.red", + "item.banner.mojang.green": "block.minecraft.banner.mojang.green", + "item.banner.mojang.brown": "block.minecraft.banner.mojang.brown", + "item.banner.mojang.blue": "block.minecraft.banner.mojang.blue", + "item.banner.mojang.purple": "block.minecraft.banner.mojang.purple", + "item.banner.mojang.cyan": "block.minecraft.banner.mojang.cyan", + "item.banner.mojang.silver": "block.minecraft.banner.mojang.light_gray", + "item.banner.mojang.gray": "block.minecraft.banner.mojang.gray", + "item.banner.mojang.pink": "block.minecraft.banner.mojang.pink", + "item.banner.mojang.lime": "block.minecraft.banner.mojang.lime", + "item.banner.mojang.yellow": "block.minecraft.banner.mojang.yellow", + "item.banner.mojang.lightBlue": "block.minecraft.banner.mojang.light_blue", + "item.banner.mojang.magenta": "block.minecraft.banner.mojang.magenta", + "item.banner.mojang.orange": "block.minecraft.banner.mojang.orange", + "item.banner.mojang.white": "block.minecraft.banner.mojang.white", + "item.banner.straight_cross.black": "block.minecraft.banner.straight_cross.black", + "item.banner.straight_cross.red": "block.minecraft.banner.straight_cross.red", + "item.banner.straight_cross.green": "block.minecraft.banner.straight_cross.green", + "item.banner.straight_cross.brown": "block.minecraft.banner.straight_cross.brown", + "item.banner.straight_cross.blue": "block.minecraft.banner.straight_cross.blue", + "item.banner.straight_cross.purple": "block.minecraft.banner.straight_cross.purple", + "item.banner.straight_cross.cyan": "block.minecraft.banner.straight_cross.cyan", + "item.banner.straight_cross.silver": "block.minecraft.banner.straight_cross.light_gray", + "item.banner.straight_cross.gray": "block.minecraft.banner.straight_cross.gray", + "item.banner.straight_cross.pink": "block.minecraft.banner.straight_cross.pink", + "item.banner.straight_cross.lime": "block.minecraft.banner.straight_cross.lime", + "item.banner.straight_cross.yellow": "block.minecraft.banner.straight_cross.yellow", + "item.banner.straight_cross.lightBlue": "block.minecraft.banner.straight_cross.light_blue", + "item.banner.straight_cross.magenta": "block.minecraft.banner.straight_cross.magenta", + "item.banner.straight_cross.orange": "block.minecraft.banner.straight_cross.orange", + "item.banner.straight_cross.white": "block.minecraft.banner.straight_cross.white", + "subtitles.block.note.note": "subtitles.block.note_block.note", + "subtitles.entity.armorstand.fall": "subtitles.entity.armor_stand.fall", + "subtitles.entity.bobber.throw": "subtitles.entity.fishing_bobber.throw", + "subtitles.entity.parrot.imitate.cave_spider": "subtitles.entity.parrot.imitate.creeper", + "subtitles.entity.parrot.imitate.enderdragon": "subtitles.entity.parrot.imitate.ender_dragon", + "subtitles.entity.parrot.imitate.evocation_illager": "subtitles.entity.parrot.imitate.evoker", + "subtitles.entity.parrot.imitate.illusion_illager": "subtitles.entity.parrot.imitate.evoker", + "subtitles.entity.parrot.imitate.magmacube": "subtitles.entity.parrot.imitate.magma_cube", + "subtitles.entity.parrot.imitate.polar_bear": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.parrot.imitate.silverfish": "subtitles.entity.parrot.imitate.creeper", + "subtitles.entity.parrot.imitate.slime": "subtitles.entity.parrot.imitate.magma_cube", + "subtitles.entity.parrot.imitate.spider": "subtitles.entity.parrot.imitate.creeper", + "subtitles.entity.parrot.imitate.stray": "subtitles.entity.parrot.imitate.skeleton", + "subtitles.entity.parrot.imitate.vindication_illager": "subtitles.entity.parrot.imitate.vindicator", + "subtitles.entity.parrot.imitate.wither_skeleton": "subtitles.entity.parrot.imitate.skeleton", + "subtitles.entity.parrot.imitate.zombie": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.parrot.imitate.zombie_villager": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.elder_guardian.ambient.land": "subtitles.entity.elder_guardian.ambient_land", + "subtitles.entity.enderdragon.ambient": "subtitles.entity.ender_dragon.ambient", + "subtitles.entity.enderdragon.death": "subtitles.entity.ender_dragon.death", + "subtitles.entity.enderdragon.flap": "subtitles.entity.ender_dragon.flap", + "subtitles.entity.enderdragon.growl": "subtitles.entity.ender_dragon.growl", + "subtitles.entity.enderdragon.hurt": "subtitles.entity.ender_dragon.hurt", + "subtitles.entity.enderdragon.shoot": "subtitles.entity.ender_dragon.shoot", + "subtitles.entity.endereye.launch": "subtitles.entity.ender_eye.launch", + "subtitles.entity.enderpearl.throw": "subtitles.entity.ender_pearl.throw", + "subtitles.entity.evocation_fangs.attack": "subtitles.entity.evoker_fangs.attack", + "subtitles.entity.evocation_illager.ambient": "subtitles.entity.evoker.ambient", + "subtitles.entity.evocation_illager.cast_spell": "subtitles.entity.evoker.cast_spell", + "subtitles.entity.evocation_illager.death": "subtitles.entity.evoker.death", + "subtitles.entity.evocation_illager.hurt": "subtitles.entity.evoker.hurt", + "subtitles.entity.evocation_illager.prepare_attack": "subtitles.entity.evoker.prepare_attack", + "subtitles.entity.evocation_illager.prepare_summon": "subtitles.entity.evoker.prepare_summon", + "subtitles.entity.evocation_illager.prepare_wololo": "subtitles.entity.evoker.prepare_wololo", + "subtitles.entity.firework.blast": "subtitles.entity.firework_rocket.blast", + "subtitles.entity.firework.launch": "subtitles.entity.firework_rocket.launch", + "subtitles.entity.firework.twinkle": "subtitles.entity.firework_rocket.twinkle", + "subtitles.entity.generic.big_fall": "subtitles.entity.armor_stand.fall", + "subtitles.entity.guardian.ambient.land": "subtitles.entity.guardian.ambient_land", + "subtitles.entity.horse.angry": "subtitles.entity.horse.ambient", + "subtitles.entity.illusion_illager.ambient": "subtitles.entity.illusioner.ambient", + "subtitles.entity.illusion_illager.cast_spell": "subtitles.entity.illusioner.cast_spell", + "subtitles.entity.illusion_illager.death": "subtitles.entity.illusioner.death", + "subtitles.entity.illusion_illager.hurt": "subtitles.entity.illusioner.hurt", + "subtitles.entity.illusion_illager.mirror_move": "subtitles.entity.illusioner.mirror_move", + "subtitles.entity.illusion_illager.prepare_blindness": "subtitles.entity.illusioner.prepare_blindness", + "subtitles.entity.illusion_illager.prepare_mirror": "subtitles.entity.illusioner.prepare_mirror", + "subtitles.entity.itemframe.add_item": "subtitles.entity.item_frame.add_item", + "subtitles.entity.itemframe.break": "subtitles.entity.item_frame.break", + "subtitles.entity.itemframe.place": "subtitles.entity.item_frame.place", + "subtitles.entity.itemframe.remove_item": "subtitles.entity.item_frame.remove_item", + "subtitles.entity.itemframe.rotate_item": "subtitles.entity.item_frame.rotate_item", + "subtitles.entity.leashknot.break": "subtitles.entity.leash_knot.break", + "subtitles.entity.leashknot.place": "subtitles.entity.leash_knot.place", + "subtitles.entity.lightning.impact": "subtitles.entity.lightning_bolt.impact", + "subtitles.entity.lightning.thunder": "subtitles.entity.lightning_bolt.thunder", + "subtitles.entity.magmacube.death": "subtitles.entity.magma_cube.death", + "subtitles.entity.magmacube.hurt": "subtitles.entity.magma_cube.hurt", + "subtitles.entity.magmacube.squish": "subtitles.entity.magma_cube.squish", + "subtitles.entity.pig.saddle": "subtitles.entity.horse.saddle", + "subtitles.entity.polar_bear.baby_ambient": "subtitles.entity.polar_bear.ambient_baby", + "subtitles.entity.shulker.close": "subtitles.block.shulker_box.close", + "subtitles.entity.shulker.open": "subtitles.block.shulker_box.open", + "subtitles.entity.snowman.death": "subtitles.entity.snow_golem.death", + "subtitles.entity.snowman.hurt": "subtitles.entity.snow_golem.hurt", + "subtitles.entity.villager.trading": "subtitles.entity.villager.trade", + "subtitles.entity.vindication_illager.ambient": "subtitles.entity.vindicator.ambient", + "subtitles.entity.vindication_illager.death": "subtitles.entity.vindicator.death", + "subtitles.entity.vindication_illager.hurt": "subtitles.entity.vindicator.hurt", + "subtitles.item.shear": "subtitles.item.shears.shear", + "advancements.adventure.root.title": "selectWorld.gameMode.adventure" +} \ No newline at end of file From 3fc2d28b95b63dc90851b477d9a42ca0e4099993 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Thu, 8 Nov 2018 16:18:20 -0200 Subject: [PATCH 09/24] fix npe --- .../protocols/protocol1_13to1_12_2/ChatRewriter.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java index e5081c2e4..d6e888402 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java @@ -139,8 +139,10 @@ public class ChatRewriter { if (newTranslate != null) { ((TranslatableComponent) component).setTranslate(newTranslate); } - for (BaseComponent baseComponent : ((TranslatableComponent) component).getWith()) { - processTranslate(baseComponent); + if (((TranslatableComponent) component).getWith() != null) { + for (BaseComponent baseComponent : ((TranslatableComponent) component).getWith()) { + processTranslate(baseComponent); + } } } if (component.getHoverEvent() != null) { @@ -148,8 +150,10 @@ public class ChatRewriter { processTranslate(baseComponent); } } - for (BaseComponent baseComponent : component.getExtra()) { - processTranslate(baseComponent); + if (component.getExtra() != null) { + for (BaseComponent baseComponent : component.getExtra()) { + processTranslate(baseComponent); + } } } } From 408bd491202b9c11294ad2a7d45e37f07b6e173b Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sat, 10 Nov 2018 08:41:22 -0200 Subject: [PATCH 10/24] fix set cooldown --- .../Protocol1_13_1To1_13.java | 16 ++++++++ .../Protocol1_13To1_12_2.java | 40 ++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/Protocol1_13_1To1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/Protocol1_13_1To1_13.java index ff162030d..e06278f9d 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/Protocol1_13_1To1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/Protocol1_13_1To1_13.java @@ -90,6 +90,22 @@ public class Protocol1_13_1To1_13 extends Protocol { } }); + // Set cooldown + registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // Item + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.VAR_INT, 0, + InventoryPackets.getNewItemId(wrapper.get(Type.VAR_INT, 0)) + ); + } + }); + } + }); + // Boss bar registerOutgoing(State.PLAY, 0x0C, 0x0C, new PacketRemapper() { @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index de7d4e8c0..dc44c6688 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -223,7 +223,45 @@ public class Protocol1_13To1_12_2 extends Protocol { // InventoryPackets 0x14 -> 0x15 // InventoryPackets 0x15 -> 0x16 // InventoryPackets 0x16 -> 0x17 - registerOutgoing(State.PLAY, 0x17, 0x18); + // Set cooldown + registerOutgoing(State.PLAY, 0x17, 0x18, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int item = wrapper.read(Type.VAR_INT); + int ticks = wrapper.read(Type.VAR_INT); + wrapper.cancel(); + if (item == 383) { // Spawn egg + for (int i = 0; i < 44; i++) { + Integer newItem = MappingData.oldToNewItems.get(item << 16 | i); + if (newItem != null) { + PacketWrapper packet = wrapper.create(0x18); + packet.write(Type.VAR_INT, newItem); + packet.write(Type.VAR_INT, ticks); + packet.send(Protocol1_13To1_12_2.class); + } else { + break; + } + } + } else { + for (int i = 0; i < 16; i++) { + Integer newItem = MappingData.oldToNewItems.get(item << 4 | i); + if (newItem != null) { + PacketWrapper packet = wrapper.create(0x18); + packet.write(Type.VAR_INT, newItem); + packet.write(Type.VAR_INT, ticks); + packet.send(Protocol1_13To1_12_2.class); + } else { + break; + } + } + } + } + }); + } + }); // WorldPackets 0x18 -> 0x19 registerOutgoing(State.PLAY, 0x1A, 0x1B); registerOutgoing(State.PLAY, 0x1B, 0x1C); From cfd3179cb83d3ae79571ae921d5ddc3e5e1097f9 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sun, 11 Nov 2018 11:57:33 -0200 Subject: [PATCH 11/24] try to eat less ram --- .../data/MappingData.java | 14 +- .../data/mapping-lang-1.12-1.13.json | 1071 ++++++++++++++++- 2 files changed, 1081 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java index 4ec3c9776..8fca9c3f3 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java @@ -49,7 +49,8 @@ public class MappingData { Via.getPlatform().getLogger().info("Loading sound mapping..."); soundMappings = new SoundMappingShortArray(mapping1_12.getAsJsonArray("sounds"), mapping1_13.getAsJsonArray("sounds")); Via.getPlatform().getLogger().info("Loading translation mappping"); - translateMapping = GsonUtil.getGson().fromJson( + translateMapping = new HashMap<>(); + Map translateData = GsonUtil.getGson().fromJson( new InputStreamReader( MappingData.class.getClassLoader() .getResourceAsStream("assets/viaversion/data/mapping-lang-1.12-1.13.json") @@ -65,8 +66,15 @@ public class MappingData { if (line.isEmpty()) continue; String[] keyAndTranslation = line.split("=", 2); if (keyAndTranslation.length != 2) continue; - if (!translateMapping.containsKey(keyAndTranslation[0])) { - translateMapping.put(keyAndTranslation[0], keyAndTranslation[1]); + String key = keyAndTranslation[0]; + String translation = keyAndTranslation[1]; + if (!translateData.containsKey(key)) { + translateMapping.put(key, translation); + } else { + String dataValue = translateData.get(keyAndTranslation[0]); + if (dataValue != null) { + translateMapping.put(key, dataValue); + } } } } catch (IOException e) { diff --git a/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json index 585c3981f..7fcc2d5c3 100644 --- a/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json +++ b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json @@ -1,30 +1,504 @@ { + "language.name": null, + "language.region": null, + "language.code": null, + "gui.done": null, + "gui.cancel": null, + "gui.back": null, + "gui.toTitle": null, + "gui.toMenu": null, + "gui.up": null, + "gui.down": null, + "gui.yes": null, + "gui.no": null, + "gui.none": null, + "gui.all": null, + "gui.recipebook.moreRecipes": null, + "gui.recipebook.toggleRecipes.all": null, + "gui.recipebook.toggleRecipes.craftable": null, + "translation.test.none": null, + "translation.test.complex": null, + "translation.test.escape": null, + "translation.test.invalid": null, + "translation.test.invalid2": null, + "translation.test.args": null, + "translation.test.world": null, + "menu.game": null, + "menu.singleplayer": null, + "menu.multiplayer": null, + "menu.online": null, + "menu.options": null, + "menu.quit": null, + "menu.returnToMenu": null, + "menu.disconnect": null, + "menu.returnToGame": null, + "menu.generatingLevel": null, + "menu.loadingLevel": null, + "menu.generatingTerrain": null, + "menu.convertingLevel": null, + "menu.respawning": null, + "menu.shareToLan": null, + "selectWorld.title": null, + "selectWorld.empty": null, + "selectWorld.world": null, + "selectWorld.select": null, + "selectWorld.create": null, + "selectWorld.recreate": null, + "selectWorld.createDemo": null, + "selectWorld.delete": null, + "selectWorld.edit": null, + "selectWorld.edit.title": null, + "selectWorld.edit.resetIcon": null, + "selectWorld.deleteQuestion": null, "selectWorld.deleteButton": "selectWorld.delete", + "selectWorld.conversion": null, + "selectWorld.newWorld": null, + "selectWorld.newWorld.copyOf": null, + "selectWorld.enterName": null, + "selectWorld.resultFolder": null, + "selectWorld.enterSeed": null, + "selectWorld.seedInfo": null, + "selectWorld.cheats": null, + "selectWorld.customizeType": null, + "selectWorld.version": null, + "selectWorld.versionUnknown": null, + "selectWorld.versionQuestion": null, + "selectWorld.tooltip.fromNewerVersion1": null, + "selectWorld.tooltip.fromNewerVersion2": null, + "selectWorld.tooltip.snapshot1": null, + "selectWorld.tooltip.snapshot2": null, + "selectWorld.unable_to_load": null, + "selectWorld.load_folder_access": null, + "createWorld.customize.presets": null, + "createWorld.customize.presets.title": null, + "createWorld.customize.presets.select": null, + "createWorld.customize.presets.share": null, + "createWorld.customize.presets.list": null, + "createWorld.customize.flat.title": null, + "createWorld.customize.flat.tile": null, + "createWorld.customize.flat.height": null, + "createWorld.customize.flat.addLayer": null, + "createWorld.customize.flat.editLayer": null, + "createWorld.customize.flat.removeLayer": null, + "createWorld.customize.flat.layer.top": null, + "createWorld.customize.flat.layer": null, + "createWorld.customize.flat.layer.bottom": null, + "createWorld.customize.preset.classic_flat": null, + "createWorld.customize.preset.tunnelers_dream": null, + "createWorld.customize.preset.water_world": null, + "createWorld.customize.preset.overworld": null, + "createWorld.customize.preset.snowy_kingdom": null, + "createWorld.customize.preset.bottomless_pit": null, + "createWorld.customize.preset.desert": null, + "createWorld.customize.preset.redstone_ready": null, + "createWorld.customize.preset.the_void": null, + "createWorld.customize.custom.page0": null, + "createWorld.customize.custom.page1": null, + "createWorld.customize.custom.page2": null, + "createWorld.customize.custom.page3": null, + "createWorld.customize.custom.randomize": null, + "createWorld.customize.custom.prev": null, + "createWorld.customize.custom.next": null, + "createWorld.customize.custom.defaults": null, + "createWorld.customize.custom.confirm1": null, + "createWorld.customize.custom.confirm2": null, + "createWorld.customize.custom.confirmTitle": null, + "createWorld.customize.custom.mainNoiseScaleX": null, + "createWorld.customize.custom.mainNoiseScaleY": null, + "createWorld.customize.custom.mainNoiseScaleZ": null, + "createWorld.customize.custom.depthNoiseScaleX": null, + "createWorld.customize.custom.depthNoiseScaleZ": null, + "createWorld.customize.custom.depthNoiseScaleExponent": null, + "createWorld.customize.custom.baseSize": null, + "createWorld.customize.custom.coordinateScale": null, + "createWorld.customize.custom.heightScale": null, + "createWorld.customize.custom.stretchY": null, + "createWorld.customize.custom.upperLimitScale": null, + "createWorld.customize.custom.lowerLimitScale": null, + "createWorld.customize.custom.biomeDepthWeight": null, + "createWorld.customize.custom.biomeDepthOffset": null, + "createWorld.customize.custom.biomeScaleWeight": null, + "createWorld.customize.custom.biomeScaleOffset": null, + "createWorld.customize.custom.seaLevel": null, + "createWorld.customize.custom.useCaves": null, + "createWorld.customize.custom.useStrongholds": null, + "createWorld.customize.custom.useVillages": null, + "createWorld.customize.custom.useMineShafts": null, + "createWorld.customize.custom.useTemples": null, + "createWorld.customize.custom.useMonuments": null, + "createWorld.customize.custom.useMansions": null, + "createWorld.customize.custom.useRavines": null, + "createWorld.customize.custom.useDungeons": null, + "createWorld.customize.custom.dungeonChance": null, + "createWorld.customize.custom.useWaterLakes": null, + "createWorld.customize.custom.waterLakeChance": null, + "createWorld.customize.custom.useLavaLakes": null, + "createWorld.customize.custom.lavaLakeChance": null, + "createWorld.customize.custom.useLavaOceans": null, + "createWorld.customize.custom.fixedBiome": null, + "createWorld.customize.custom.biomeSize": null, + "createWorld.customize.custom.riverSize": null, + "createWorld.customize.custom.size": null, + "createWorld.customize.custom.count": null, + "createWorld.customize.custom.minHeight": null, + "createWorld.customize.custom.maxHeight": null, + "createWorld.customize.custom.center": null, + "createWorld.customize.custom.spread": null, + "createWorld.customize.custom.presets.title": null, "createWorld.customize.custom.presets": "createWorld.customize.presets", "createWorld.customize.custom.preset.waterWorld": "createWorld.customize.preset.water_world", + "createWorld.customize.custom.preset.isleLand": null, + "createWorld.customize.custom.preset.caveDelight": null, + "createWorld.customize.custom.preset.mountains": null, + "createWorld.customize.custom.preset.drought": null, + "createWorld.customize.custom.preset.caveChaos": null, + "createWorld.customize.custom.preset.goodLuck": null, + "gameMode.survival": null, + "gameMode.creative": null, + "gameMode.adventure": null, + "gameMode.spectator": null, + "gameMode.hardcore": null, + "gameMode.changed": null, "spectatorMenu.previous_page": "createWorld.customize.custom.prev", "spectatorMenu.next_page": "createWorld.customize.custom.next", + "spectatorMenu.close": null, + "spectatorMenu.teleport": null, + "spectatorMenu.teleport.prompt": null, + "spectatorMenu.team_teleport": null, + "spectatorMenu.team_teleport.prompt": null, + "spectatorMenu.root.prompt": null, + "selectWorld.gameMode": null, + "selectWorld.gameMode.survival": null, + "selectWorld.gameMode.survival.line1": null, + "selectWorld.gameMode.survival.line2": null, + "selectWorld.gameMode.creative": null, + "selectWorld.gameMode.creative.line1": null, + "selectWorld.gameMode.creative.line2": null, + "selectWorld.gameMode.spectator": null, + "selectWorld.gameMode.spectator.line1": null, + "selectWorld.gameMode.spectator.line2": null, + "selectWorld.gameMode.hardcore": null, + "selectWorld.gameMode.hardcore.line1": null, + "selectWorld.gameMode.hardcore.line2": null, + "selectWorld.gameMode.adventure": null, + "selectWorld.gameMode.adventure.line1": null, + "selectWorld.gameMode.adventure.line2": null, + "selectWorld.moreWorldOptions": null, + "selectWorld.mapFeatures": null, + "selectWorld.mapFeatures.info": null, + "selectWorld.mapType": null, + "selectWorld.mapType.normal": null, + "selectWorld.allowCommands": null, + "selectWorld.hardcoreMode": null, + "selectWorld.hardcoreMode.info": null, + "selectWorld.bonusItems": null, + "generator.default": null, + "generator.flat": null, + "generator.largeBiomes": null, + "generator.amplified": null, + "generator.customized": null, + "generator.debug_all_block_states": null, + "generator.amplified.info": null, + "selectServer.title": null, "selectServer.empty": "selectWorld.empty", + "selectServer.select": null, + "selectServer.direct": null, "selectServer.edit": "selectWorld.edit", "selectServer.delete": "selectWorld.delete", + "selectServer.add": null, + "selectServer.defaultName": null, + "selectServer.deleteQuestion": null, "selectServer.deleteButton": "selectWorld.delete", + "selectServer.refresh": null, + "selectServer.hiddenAddress": null, + "addServer.title": null, + "addServer.enterName": null, + "addServer.enterIp": null, "addServer.add": "gui.done", + "addServer.hideAddress": null, + "addServer.resourcePack": null, + "addServer.resourcePack.enabled": null, + "addServer.resourcePack.disabled": null, + "addServer.resourcePack.prompt": null, + "lanServer.title": null, + "lanServer.scanning": null, + "lanServer.start": null, + "lanServer.otherPlayers": null, + "mcoServer.title": null, + "multiplayer.title": null, + "multiplayer.connect": null, + "multiplayer.ipinfo": null, + "multiplayer.texturePrompt.line1": null, + "multiplayer.texturePrompt.line2": null, + "multiplayer.downloadingStats": null, + "multiplayer.stopSleeping": null, + "multiplayer.player.joined": null, + "multiplayer.player.joined.renamed": null, + "multiplayer.player.left": null, + "multiplayer.status.and_more": null, + "multiplayer.status.cancelled": null, + "multiplayer.status.cannot_connect": null, + "multiplayer.status.cannot_resolve": null, + "multiplayer.status.client_out_of_date": null, + "multiplayer.status.no_connection": null, + "multiplayer.status.old": null, + "multiplayer.status.pinging": null, + "multiplayer.status.server_out_of_date": null, + "multiplayer.status.unknown": null, + "multiplayer.status.unrequested": null, + "multiplayer.disconnect.authservers_down": null, + "multiplayer.disconnect.duplicate_login": null, + "multiplayer.disconnect.flying": null, + "multiplayer.disconnect.generic": null, + "multiplayer.disconnect.idling": null, + "multiplayer.disconnect.illegal_characters": null, + "multiplayer.disconnect.invalid_entity_attacked": null, + "multiplayer.disconnect.invalid_player_movement": null, + "multiplayer.disconnect.invalid_vehicle_movement": null, + "multiplayer.disconnect.outdated_client": null, + "multiplayer.disconnect.outdated_server": null, + "multiplayer.disconnect.server_shutdown": null, + "multiplayer.disconnect.slow_login": null, + "multiplayer.disconnect.unverified_username": null, + "chat.cannotSend": null, + "chat.type.text": null, + "chat.type.text.narrate": null, + "chat.type.emote": null, + "chat.type.announcement": null, + "chat.type.admin": null, + "chat.type.advancement.task": null, + "chat.type.advancement.challenge": null, + "chat.type.advancement.goal": null, + "chat.link.confirm": null, + "chat.link.warning": null, + "chat.copy": null, + "chat.link.confirmTrusted": null, + "chat.link.open": null, + "menu.playdemo": null, + "menu.resetdemo": null, + "demo.day.1": null, + "demo.day.2": null, + "demo.day.3": null, + "demo.day.4": null, + "demo.day.5": null, + "demo.day.warning": null, + "demo.reminder": null, + "demo.remainingTime": null, + "demo.demoExpired": null, + "demo.help.movement": null, + "demo.help.movementShort": null, + "demo.help.movementMouse": null, + "demo.help.jump": null, + "demo.help.inventory": null, + "demo.help.title": null, + "demo.help.fullWrapped": null, + "demo.help.buy": null, + "demo.help.later": null, + "connect.connecting": null, + "connect.authorizing": null, + "connect.failed": null, "disconnect.genericReason": "createWorld.customize.flat.layer", + "disconnect.disconnected": null, + "disconnect.lost": null, + "disconnect.kicked": null, + "disconnect.timeout": null, + "disconnect.closed": null, + "disconnect.loginFailedInfo.serversUnavailable": null, + "disconnect.loginFailedInfo.invalidSession": null, "disconnect.quitting": "multiplayer.status.quitting", + "disconnect.endOfStream": null, + "disconnect.overflow": null, + "disconnect.spam": null, + "soundCategory.master": null, + "soundCategory.music": null, + "soundCategory.record": null, + "soundCategory.weather": null, + "soundCategory.hostile": null, + "soundCategory.neutral": null, + "soundCategory.player": null, + "soundCategory.block": null, + "soundCategory.ambient": null, + "soundCategory.voice": null, + "record.nowPlaying": null, + "options.off": null, + "options.on": null, + "options.visible": null, + "options.hidden": null, + "options.title": null, + "options.controls": null, + "options.video": null, + "options.language": null, + "options.sounds": null, + "options.sounds.title": null, + "options.languageWarning": null, + "options.videoTitle": null, + "options.customizeTitle": null, "options.music": "soundCategory.music", + "options.sound": null, + "options.invertMouse": null, + "options.fov": null, "options.fov.min": "selectWorld.mapType.normal", + "options.fov.max": null, + "options.saturation": null, + "options.gamma": null, + "options.gamma.min": null, + "options.gamma.max": null, + "options.sensitivity": null, + "options.sensitivity.min": null, + "options.sensitivity.max": null, + "options.renderDistance": null, + "options.viewBobbing": null, + "options.ao": null, "options.ao.off": "options.off", + "options.ao.min": null, + "options.ao.max": null, + "options.anaglyph": null, + "options.chunks": null, + "options.framerate": null, + "options.framerateLimit": null, + "options.framerateLimit.max": null, + "options.difficulty": null, + "options.difficulty.peaceful": null, + "options.difficulty.easy": null, "options.difficulty.normal": "selectWorld.mapType.normal", + "options.difficulty.hard": null, "options.difficulty.hardcore": "selectWorld.gameMode.hardcore", + "options.graphics": null, + "options.graphics.fancy": null, + "options.graphics.fast": null, "options.clouds.fancy": "options.graphics.fancy", "options.clouds.fast": "options.graphics.fast", + "options.guiScale": null, + "options.guiScale.auto": null, "options.guiScale.normal": "selectWorld.mapType.normal", + "options.renderClouds": null, + "options.particles": null, "options.particles.all": "gui.all", + "options.particles.decreased": null, + "options.particles.minimal": null, + "options.multiplayer.title": null, + "options.chat.title": null, + "options.chat.visibility": null, "options.chat.visibility.full": "options.visible", + "options.chat.visibility.system": null, "options.chat.visibility.hidden": "options.hidden", + "options.chat.color": null, + "options.chat.opacity": null, + "options.chat.links": null, + "options.chat.links.prompt": null, + "options.chat.scale": null, + "options.chat.width": null, + "options.chat.height.focused": null, + "options.chat.height.unfocused": null, + "options.skinCustomisation": null, + "options.skinCustomisation.title": null, + "options.modelPart.cape": null, + "options.modelPart.hat": null, + "options.modelPart.jacket": null, + "options.modelPart.left_sleeve": null, + "options.modelPart.right_sleeve": null, + "options.modelPart.left_pants_leg": null, + "options.modelPart.right_pants_leg": null, + "options.snooper": null, + "options.snooper.view": null, + "options.snooper.title": null, + "options.snooper.desc": null, + "options.resourcepack": null, + "options.fullscreen": null, + "options.vsync": null, + "options.vbo": null, + "options.touchscreen": null, + "options.reducedDebugInfo": null, + "options.entityShadows": null, + "options.mainHand": null, + "options.mainHand.left": null, + "options.mainHand.right": null, + "options.attackIndicator": null, + "options.attack.crosshair": null, + "options.attack.hotbar": null, + "options.showSubtitles": null, + "options.realmsNotifications": null, + "options.autoJump": null, + "options.narrator": null, + "options.narrator.all": null, + "options.narrator.chat": null, + "options.narrator.system": null, + "options.narrator.notavailable": null, + "options.mipmapLevels": null, + "options.forceUnicodeFont": null, + "narrator.toast.disabled": null, + "narrator.toast.enabled": null, + "difficulty.lock.title": null, + "difficulty.lock.question": null, + "title.oldgl1": null, + "title.oldgl2": null, + "controls.title": null, + "controls.reset": null, + "controls.resetAll": null, + "key.sprint": null, + "key.forward": null, + "key.left": null, + "key.back": null, + "key.right": null, + "key.jump": null, + "key.inventory": null, + "key.drop": null, + "key.swapHands": null, + "key.chat": null, + "key.sneak": null, + "key.playerlist": null, + "key.attack": null, + "key.use": null, + "key.pickItem": null, "key.mouseButton": "key.mouse", + "key.command": null, + "key.screenshot": null, + "key.togglePerspective": null, + "key.smoothCamera": null, + "key.fullscreen": null, + "key.spectatorOutlines": null, + "key.hotbar.1": null, + "key.hotbar.2": null, + "key.hotbar.3": null, + "key.hotbar.4": null, + "key.hotbar.5": null, + "key.hotbar.6": null, + "key.hotbar.7": null, + "key.hotbar.8": null, + "key.hotbar.9": null, + "key.saveToolbarActivator": null, + "key.loadToolbarActivator": null, + "key.advancements": null, + "key.categories.movement": null, + "key.categories.misc": null, "key.categories.multiplayer": "menu.multiplayer", + "key.categories.gameplay": null, + "key.categories.ui": null, + "key.categories.inventory": null, "key.categories.creative": "gameMode.creative", + "resourcePack.openFolder": null, + "resourcePack.title": null, + "resourcePack.available.title": null, + "resourcePack.selected.title": null, + "resourcePack.folderInfo": null, + "resourcePack.incompatible": null, + "resourcePack.incompatible.old": null, + "resourcePack.incompatible.new": null, + "resourcePack.incompatible.confirm.title": null, + "resourcePack.incompatible.confirm.old": null, + "resourcePack.incompatible.confirm.new": null, + "sign.edit": null, + "book.pageIndicator": null, + "book.byAuthor": null, + "book.signButton": null, + "book.editTitle": null, + "book.finalizeButton": null, + "book.finalizeWarning": null, + "book.generation.0": null, + "book.generation.1": null, + "book.generation.2": null, + "book.generation.3": null, + "merchant.deprecated": null, "tile.air.name": "block.minecraft.air", "tile.barrier.name": "block.minecraft.barrier", "tile.stone.stone.name": "block.minecraft.stone", @@ -650,15 +1124,73 @@ "item.ironNugget.name": "item.minecraft.iron_nugget", "item.knowledgeBook.name": "item.minecraft.knowledge_book", "container.inventory": "key.categories.inventory", + "container.hopper": null, + "container.crafting": null, "container.dispenser": "block.minecraft.dispenser", "container.dropper": "block.minecraft.dropper", "container.furnace": "block.minecraft.furnace", + "container.enchant": null, + "container.enchant.lapis.one": null, + "container.enchant.lapis.many": null, + "container.enchant.level.one": null, + "container.enchant.level.many": null, + "container.enchant.level.requirement": null, + "container.enchant.clue": null, + "container.repair": null, + "container.repair.cost": null, + "container.repair.expensive": null, + "container.creative": null, "container.brewing": "block.minecraft.brewing_stand", "container.chest": "block.minecraft.chest", + "container.chestDouble": null, "container.enderchest": "block.minecraft.ender_chest", "container.beacon": "block.minecraft.beacon", "container.shulkerBox": "block.minecraft.shulker_box", + "container.shulkerBox.more": null, + "container.spectatorCantOpen": null, + "container.isLocked": null, + "structure_block.save_success": null, + "structure_block.save_failure": null, + "structure_block.load_success": null, + "structure_block.load_prepare": null, + "structure_block.load_not_found": null, + "structure_block.size_success": null, "structure_block.mode.save": "selectWorld.edit.save", + "structure_block.mode.load": null, + "structure_block.mode.data": null, + "structure_block.mode.corner": null, + "structure_block.hover.save": null, + "structure_block.hover.load": null, + "structure_block.hover.data": null, + "structure_block.hover.corner": null, + "structure_block.mode_info.save": null, + "structure_block.mode_info.load": null, + "structure_block.mode_info.data": null, + "structure_block.mode_info.corner": null, + "structure_block.structure_name": null, + "structure_block.custom_data": null, + "structure_block.position": null, + "structure_block.size": null, + "structure_block.integrity": null, + "structure_block.include_entities": null, + "structure_block.detect_size": null, + "structure_block.button.detect_size": null, + "structure_block.button.save": null, + "structure_block.button.load": null, + "structure_block.show_air": null, + "structure_block.show_boundingbox": null, + "item.dyed": null, + "item.unbreakable": null, + "item.canBreak": null, + "item.canPlace": null, + "item.color": null, + "item.nbt_tags": null, + "item.durability": null, + "filled_map.mansion": null, + "filled_map.monument": null, + "filled_map.unknown": null, + "filled_map.level": null, + "filled_map.scale": null, "entity.Item.name": "entity.minecraft.item", "entity.XPOrb.name": "entity.minecraft.experience_orb", "entity.SmallFireball.name": "entity.minecraft.small_fireball", @@ -739,8 +1271,64 @@ "entity.MinecartChest.name": "item.minecraft.chest_minecart", "entity.Boat.name": "entity.minecraft.boat", "entity.generic.name": "selectWorld.versionUnknown", + "death.fell.accident.ladder": null, + "death.fell.accident.vines": null, + "death.fell.accident.water": null, + "death.fell.accident.generic": null, + "death.fell.killer": null, + "death.fell.assist": null, + "death.fell.assist.item": null, + "death.fell.finish": null, + "death.fell.finish.item": null, + "death.attack.lightningBolt": null, + "death.attack.inFire": null, + "death.attack.inFire.player": null, + "death.attack.onFire": null, + "death.attack.onFire.player": null, + "death.attack.lava": null, + "death.attack.lava.player": null, + "death.attack.hotFloor.player": null, + "death.attack.inWall": null, + "death.attack.cramming": null, + "death.attack.drown": null, + "death.attack.drown.player": null, + "death.attack.starve": null, + "death.attack.cactus": null, + "death.attack.cactus.player": null, + "death.attack.generic": null, + "death.attack.explosion": null, + "death.attack.explosion.player": null, + "death.attack.magic": null, + "death.attack.wither": null, + "death.attack.anvil": null, + "death.attack.fallingBlock": null, + "death.attack.mob": null, "death.attack.player": "death.attack.mob", "death.attack.player.item": "death.attack.mob.item", + "death.attack.arrow": null, + "death.attack.arrow.item": null, + "death.attack.fireball": null, + "death.attack.fireball.item": null, + "death.attack.thrown": null, + "death.attack.thrown.item": null, + "death.attack.indirectMagic": null, + "death.attack.indirectMagic.item": null, + "death.attack.thorns": null, + "death.attack.fall": null, + "death.attack.outOfWorld": null, + "death.attack.dragonBreath": null, + "death.attack.flyIntoWall": null, + "death.attack.fireworks": null, + "deathScreen.respawn": null, + "deathScreen.spectate": null, + "deathScreen.deleteWorld": null, + "deathScreen.titleScreen": null, + "deathScreen.score": null, + "deathScreen.title.hardcore": null, + "deathScreen.title": null, + "deathScreen.leaveServer": null, + "deathScreen.quit.confirm": null, + "effect.none": null, "effect.moveSpeed": "effect.minecraft.speed", "effect.moveSlowdown": "effect.minecraft.slowness", "effect.digSpeed": "effect.minecraft.haste", @@ -788,6 +1376,7 @@ "tipped_arrow.effect.weakness": "item.minecraft.tipped_arrow.effect.weakness", "tipped_arrow.effect.levitation": "item.minecraft.tipped_arrow.effect.levitation", "tipped_arrow.effect.luck": "item.minecraft.tipped_arrow.effect.luck", + "potion.whenDrank": null, "potion.effect.empty": "item.minecraft.potion.effect.empty", "potion.effect.water": "item.minecraft.potion.effect.water", "potion.effect.mundane": "item.minecraft.potion.effect.mundane", @@ -849,6 +1438,8 @@ "lingering_potion.effect.levitation": "item.minecraft.lingering_potion.effect.levitation", "lingering_potion.effect.luck": "item.minecraft.lingering_potion.effect.luck", "potion.potency.0": "selectWorld.gameMode.spectator.line2", + "potion.potency.1": null, + "potion.potency.2": null, "enchantment.damage.all": "enchantment.minecraft.sharpness", "enchantment.damage.undead": "enchantment.minecraft.smite", "enchantment.damage.arthropods": "enchantment.minecraft.bane_of_arthropods", @@ -879,13 +1470,27 @@ "enchantment.mending": "enchantment.minecraft.mending", "enchantment.binding_curse": "enchantment.minecraft.binding_curse", "enchantment.vanishing_curse": "enchantment.minecraft.vanishing_curse", + "enchantment.level.1": null, "enchantment.level.2": "potion.potency.1", "enchantment.level.3": "potion.potency.2", "enchantment.level.4": "potion.potency.3", "enchantment.level.5": "potion.potency.4", "enchantment.level.6": "potion.potency.5", + "enchantment.level.7": null, + "enchantment.level.8": null, + "enchantment.level.9": null, + "enchantment.level.10": null, "gui.advancements": "key.advancements", + "gui.stats": null, + "advancements.empty": null, + "advancements.toast.task": null, + "advancements.toast.challenge": null, + "advancements.toast.goal": null, + "stats.tooltip.type.statistic": null, + "stat.generalButton": null, "stat.blocksButton": "soundCategory.block", + "stat.itemsButton": null, + "stat.mobsButton": null, "stat.used": "stat_type.minecraft.used", "stat.mined": "stat_type.minecraft.mined", "stat.crafted": "stat_type.minecraft.crafted", @@ -945,7 +1550,10 @@ "stat.chestOpened": "stat.minecraft.open_chest", "stat.shulkerBoxOpened": "stat.minecraft.open_shulker_box", "stat.sleepInBed": "stat.minecraft.sleep_in_bed", + "recipe.toast.title": null, + "recipe.toast.description": null, "commands.setblock.success": "subtitles.block.generic.place", + "commands.time.set": null, "commands.kill.successful": "commands.kill.success.single", "commands.save-on.alreadyOn": "commands.save.alreadyOn", "commands.save-off.alreadyOff": "commands.save.alreadyOff", @@ -953,17 +1561,84 @@ "commands.tp.success": "commands.teleport.success.entity.single", "commands.tp.success.coordinates": "commands.teleport.success.location.single", "commands.teleport.success.coordinates": "commands.teleport.success.location.single", + "commands.whitelist.reloaded": null, + "commands.whitelist.add.success": null, + "commands.whitelist.remove.success": null, + "commands.advancement.advancementNotFound": null, "commands.scoreboard.players.enable.success": "commands.scoreboard.players.enable.success.single", "commands.scoreboard.teams.remove.success": "commands.team.remove.success", + "commands.gamemode.success.self": null, + "commands.gamemode.success.other": null, + "commands.publish.started": null, + "commands.publish.failed": null, "commands.debug.start": "commands.debug.started", + "commands.message.display.outgoing": null, + "commands.message.display.incoming": null, + "commands.seed.success": null, + "itemGroup.buildingBlocks": null, + "itemGroup.decorations": null, "itemGroup.redstone": "item.minecraft.redstone", + "itemGroup.transportation": null, "itemGroup.misc": "key.categories.misc", + "itemGroup.search": null, + "itemGroup.food": null, + "itemGroup.tools": null, + "itemGroup.combat": null, + "itemGroup.brewing": null, + "itemGroup.materials": null, + "itemGroup.inventory": null, + "itemGroup.hotbar": null, + "inventory.binSlot": null, + "inventory.hotbarSaved": null, + "inventory.hotbarInfo": null, + "advMode.setCommand": null, + "advMode.setCommand.success": null, + "advMode.command": null, + "advMode.nearestPlayer": null, + "advMode.randomPlayer": null, + "advMode.allPlayers": null, + "advMode.allEntities": null, + "advMode.self": null, + "advMode.previousOutput": null, + "advMode.mode.sequence": null, + "advMode.mode.auto": null, + "advMode.mode.redstone": null, + "advMode.mode.conditional": null, + "advMode.mode.unconditional": null, + "advMode.mode.redstoneTriggered": null, + "advMode.mode.autoexec.bat": null, + "advMode.notEnabled": null, + "advMode.notAllowed": null, + "mount.onboard": null, + "build.tooHigh": null, + "item.modifiers.mainhand": null, + "item.modifiers.offhand": null, + "item.modifiers.feet": null, + "item.modifiers.legs": null, + "item.modifiers.chest": null, + "item.modifiers.head": null, + "attribute.modifier.plus.0": null, + "attribute.modifier.plus.1": null, "attribute.modifier.plus.2": "attribute.modifier.plus.1", + "attribute.modifier.take.0": null, + "attribute.modifier.take.1": null, "attribute.modifier.take.2": "attribute.modifier.take.1", "attribute.modifier.equals.0": "translation.test.args", + "attribute.modifier.equals.1": null, "attribute.modifier.equals.2": "attribute.modifier.equals.1", + "attribute.name.horse.jumpStrength": null, + "attribute.name.zombie.spawnReinforcements": null, + "attribute.name.generic.maxHealth": null, + "attribute.name.generic.followRange": null, + "attribute.name.generic.knockbackResistance": null, "attribute.name.generic.movementSpeed": "effect.minecraft.speed", + "attribute.name.generic.attackDamage": null, + "attribute.name.generic.attackSpeed": null, "attribute.name.generic.luck": "effect.minecraft.luck", + "attribute.name.generic.armor": null, + "attribute.name.generic.armorToughness": null, + "screenshot.success": null, + "screenshot.failure": null, "item.banner.black.name": "block.minecraft.black_banner", "item.banner.red.name": "block.minecraft.red_banner", "item.banner.green.name": "block.minecraft.green_banner", @@ -1605,24 +2280,119 @@ "item.banner.straight_cross.magenta": "block.minecraft.banner.straight_cross.magenta", "item.banner.straight_cross.orange": "block.minecraft.banner.straight_cross.orange", "item.banner.straight_cross.white": "block.minecraft.banner.straight_cross.white", + "subtitles.ambient.cave": null, + "subtitles.block.anvil.destroy": null, + "subtitles.block.anvil.land": null, + "subtitles.block.anvil.use": null, + "subtitles.block.brewing_stand.brew": null, + "subtitles.block.button.click": null, + "subtitles.block.chest.close": null, + "subtitles.block.chest.locked": null, + "subtitles.block.chest.open": null, + "subtitles.block.chorus_flower.death": null, + "subtitles.block.chorus_flower.grow": null, + "subtitles.block.comparator.click": null, + "subtitles.block.dispenser.dispense": null, + "subtitles.block.dispenser.fail": null, + "subtitles.block.door.toggle": null, + "subtitles.block.fence_gate.toggle": null, + "subtitles.block.fire.ambient": null, + "subtitles.block.fire.extinguish": null, + "subtitles.block.furnace.fire_crackle": null, + "subtitles.block.generic.break": null, + "subtitles.block.generic.footsteps": null, + "subtitles.block.generic.hit": null, + "subtitles.block.generic.place": null, + "subtitles.block.iron_trapdoor.close": null, + "subtitles.block.iron_trapdoor.open": null, + "subtitles.block.lava.ambient": null, + "subtitles.block.lava.extinguish": null, + "subtitles.block.lever.click": null, "subtitles.block.note.note": "subtitles.block.note_block.note", + "subtitles.block.piston.move": null, + "subtitles.block.portal.ambient": null, + "subtitles.block.pressure_plate.click": null, + "subtitles.block.redstone_torch.burnout": null, + "subtitles.block.shulker_box.close": null, + "subtitles.block.shulker_box.open": null, + "subtitles.block.trapdoor.toggle": null, + "subtitles.block.tripwire.attach": null, + "subtitles.block.tripwire.click": null, + "subtitles.block.tripwire.detach": null, + "subtitles.block.water.ambient": null, + "subtitles.enchant.thorns.hit": null, "subtitles.entity.armorstand.fall": "subtitles.entity.armor_stand.fall", + "subtitles.entity.arrow.hit": null, + "subtitles.entity.arrow.hit_player": null, + "subtitles.entity.arrow.shoot": null, + "subtitles.entity.bat.ambient": null, + "subtitles.entity.bat.death": null, + "subtitles.entity.bat.hurt": null, + "subtitles.entity.bat.takeoff": null, + "subtitles.entity.blaze.ambient": null, + "subtitles.entity.blaze.burn": null, + "subtitles.entity.blaze.death": null, + "subtitles.entity.blaze.hurt": null, + "subtitles.entity.blaze.shoot": null, "subtitles.entity.bobber.throw": "subtitles.entity.fishing_bobber.throw", + "subtitles.entity.cat.ambient": null, + "subtitles.entity.cat.death": null, + "subtitles.entity.cat.hurt": null, + "subtitles.entity.chicken.ambient": null, + "subtitles.entity.chicken.death": null, + "subtitles.entity.chicken.egg": null, + "subtitles.entity.chicken.hurt": null, + "subtitles.entity.parrot.ambient": null, + "subtitles.entity.parrot.death": null, + "subtitles.entity.parrot.eats": null, + "subtitles.entity.parrot.hurts": null, + "subtitles.entity.parrot.imitate.blaze": null, "subtitles.entity.parrot.imitate.cave_spider": "subtitles.entity.parrot.imitate.creeper", + "subtitles.entity.parrot.imitate.creeper": null, + "subtitles.entity.parrot.imitate.elder_guardian": null, "subtitles.entity.parrot.imitate.enderdragon": "subtitles.entity.parrot.imitate.ender_dragon", + "subtitles.entity.parrot.imitate.enderman": null, + "subtitles.entity.parrot.imitate.endermite": null, "subtitles.entity.parrot.imitate.evocation_illager": "subtitles.entity.parrot.imitate.evoker", + "subtitles.entity.parrot.imitate.ghast": null, + "subtitles.entity.parrot.imitate.husk": null, "subtitles.entity.parrot.imitate.illusion_illager": "subtitles.entity.parrot.imitate.evoker", "subtitles.entity.parrot.imitate.magmacube": "subtitles.entity.parrot.imitate.magma_cube", "subtitles.entity.parrot.imitate.polar_bear": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.parrot.imitate.shulker": null, "subtitles.entity.parrot.imitate.silverfish": "subtitles.entity.parrot.imitate.creeper", + "subtitles.entity.parrot.imitate.skeleton": null, "subtitles.entity.parrot.imitate.slime": "subtitles.entity.parrot.imitate.magma_cube", "subtitles.entity.parrot.imitate.spider": "subtitles.entity.parrot.imitate.creeper", "subtitles.entity.parrot.imitate.stray": "subtitles.entity.parrot.imitate.skeleton", + "subtitles.entity.parrot.imitate.vex": null, "subtitles.entity.parrot.imitate.vindication_illager": "subtitles.entity.parrot.imitate.vindicator", + "subtitles.entity.parrot.imitate.witch": null, + "subtitles.entity.parrot.imitate.wither": null, "subtitles.entity.parrot.imitate.wither_skeleton": "subtitles.entity.parrot.imitate.skeleton", + "subtitles.entity.parrot.imitate.wolf": null, "subtitles.entity.parrot.imitate.zombie": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.parrot.imitate.zombie_pigman": null, "subtitles.entity.parrot.imitate.zombie_villager": "subtitles.entity.parrot.imitate.husk", + "subtitles.entity.cow.ambient": null, + "subtitles.entity.cow.death": null, + "subtitles.entity.cow.hurt": null, + "subtitles.entity.cow.milk": null, + "subtitles.entity.creeper.death": null, + "subtitles.entity.creeper.hurt": null, + "subtitles.entity.creeper.primed": null, + "subtitles.entity.donkey.ambient": null, + "subtitles.entity.donkey.angry": null, + "subtitles.entity.donkey.chest": null, + "subtitles.entity.donkey.death": null, + "subtitles.entity.donkey.hurt": null, + "subtitles.entity.egg.throw": null, "subtitles.entity.elder_guardian.ambient.land": "subtitles.entity.elder_guardian.ambient_land", + "subtitles.entity.elder_guardian.ambient": null, + "subtitles.entity.elder_guardian.curse": null, + "subtitles.entity.elder_guardian.death": null, + "subtitles.entity.elder_guardian.flop": null, + "subtitles.entity.elder_guardian.hurt": null, "subtitles.entity.enderdragon.ambient": "subtitles.entity.ender_dragon.ambient", "subtitles.entity.enderdragon.death": "subtitles.entity.ender_dragon.death", "subtitles.entity.enderdragon.flap": "subtitles.entity.ender_dragon.flap", @@ -1630,6 +2400,14 @@ "subtitles.entity.enderdragon.hurt": "subtitles.entity.ender_dragon.hurt", "subtitles.entity.enderdragon.shoot": "subtitles.entity.ender_dragon.shoot", "subtitles.entity.endereye.launch": "subtitles.entity.ender_eye.launch", + "subtitles.entity.enderman.ambient": null, + "subtitles.entity.enderman.death": null, + "subtitles.entity.enderman.hurt": null, + "subtitles.entity.enderman.stare": null, + "subtitles.entity.enderman.teleport": null, + "subtitles.entity.endermite.ambient": null, + "subtitles.entity.endermite.death": null, + "subtitles.entity.endermite.hurt": null, "subtitles.entity.enderpearl.throw": "subtitles.entity.ender_pearl.throw", "subtitles.entity.evocation_fangs.attack": "subtitles.entity.evoker_fangs.attack", "subtitles.entity.evocation_illager.ambient": "subtitles.entity.evoker.ambient", @@ -1639,12 +2417,43 @@ "subtitles.entity.evocation_illager.prepare_attack": "subtitles.entity.evoker.prepare_attack", "subtitles.entity.evocation_illager.prepare_summon": "subtitles.entity.evoker.prepare_summon", "subtitles.entity.evocation_illager.prepare_wololo": "subtitles.entity.evoker.prepare_wololo", + "subtitles.entity.experience_orb.pickup": null, "subtitles.entity.firework.blast": "subtitles.entity.firework_rocket.blast", "subtitles.entity.firework.launch": "subtitles.entity.firework_rocket.launch", "subtitles.entity.firework.twinkle": "subtitles.entity.firework_rocket.twinkle", "subtitles.entity.generic.big_fall": "subtitles.entity.armor_stand.fall", + "subtitles.entity.generic.burn": null, + "subtitles.entity.generic.death": null, + "subtitles.entity.generic.drink": null, + "subtitles.entity.generic.eat": null, + "subtitles.entity.generic.explode": null, + "subtitles.entity.generic.extinguish_fire": null, + "subtitles.entity.generic.hurt": null, + "subtitles.entity.generic.splash": null, + "subtitles.entity.generic.swim": null, + "subtitles.entity.ghast.ambient": null, + "subtitles.entity.ghast.death": null, + "subtitles.entity.ghast.hurt": null, + "subtitles.entity.ghast.shoot": null, "subtitles.entity.guardian.ambient.land": "subtitles.entity.guardian.ambient_land", + "subtitles.entity.guardian.ambient": null, + "subtitles.entity.guardian.attack": null, + "subtitles.entity.guardian.death": null, + "subtitles.entity.guardian.flop": null, + "subtitles.entity.guardian.hurt": null, + "subtitles.entity.horse.ambient": null, "subtitles.entity.horse.angry": "subtitles.entity.horse.ambient", + "subtitles.entity.horse.armor": null, + "subtitles.entity.horse.breathe": null, + "subtitles.entity.horse.death": null, + "subtitles.entity.horse.eat": null, + "subtitles.entity.horse.gallop": null, + "subtitles.entity.horse.hurt": null, + "subtitles.entity.horse.jump": null, + "subtitles.entity.horse.saddle": null, + "subtitles.entity.husk.ambient": null, + "subtitles.entity.husk.death": null, + "subtitles.entity.husk.hurt": null, "subtitles.entity.illusion_illager.ambient": "subtitles.entity.illusioner.ambient", "subtitles.entity.illusion_illager.cast_spell": "subtitles.entity.illusioner.cast_spell", "subtitles.entity.illusion_illager.death": "subtitles.entity.illusioner.death", @@ -1652,6 +2461,11 @@ "subtitles.entity.illusion_illager.mirror_move": "subtitles.entity.illusioner.mirror_move", "subtitles.entity.illusion_illager.prepare_blindness": "subtitles.entity.illusioner.prepare_blindness", "subtitles.entity.illusion_illager.prepare_mirror": "subtitles.entity.illusioner.prepare_mirror", + "subtitles.entity.iron_golem.attack": null, + "subtitles.entity.iron_golem.death": null, + "subtitles.entity.iron_golem.hurt": null, + "subtitles.entity.item.break": null, + "subtitles.entity.item.pickup": null, "subtitles.entity.itemframe.add_item": "subtitles.entity.item_frame.add_item", "subtitles.entity.itemframe.break": "subtitles.entity.item_frame.break", "subtitles.entity.itemframe.place": "subtitles.entity.item_frame.place", @@ -1661,19 +2475,274 @@ "subtitles.entity.leashknot.place": "subtitles.entity.leash_knot.place", "subtitles.entity.lightning.impact": "subtitles.entity.lightning_bolt.impact", "subtitles.entity.lightning.thunder": "subtitles.entity.lightning_bolt.thunder", + "subtitles.entity.llama.ambient": null, + "subtitles.entity.llama.chest": null, + "subtitles.entity.llama.death": null, + "subtitles.entity.llama.eat": null, + "subtitles.entity.llama.hurt": null, + "subtitles.entity.llama.spit": null, + "subtitles.entity.llama.step": null, + "subtitles.entity.llama.swag": null, "subtitles.entity.magmacube.death": "subtitles.entity.magma_cube.death", "subtitles.entity.magmacube.hurt": "subtitles.entity.magma_cube.hurt", "subtitles.entity.magmacube.squish": "subtitles.entity.magma_cube.squish", + "subtitles.entity.minecart.riding": null, + "subtitles.entity.mule.ambient": null, + "subtitles.entity.mule.chest": null, + "subtitles.entity.mule.death": null, + "subtitles.entity.mule.hurt": null, + "subtitles.entity.painting.break": null, + "subtitles.entity.painting.place": null, + "subtitles.entity.pig.ambient": null, + "subtitles.entity.pig.death": null, + "subtitles.entity.pig.hurt": null, "subtitles.entity.pig.saddle": "subtitles.entity.horse.saddle", + "subtitles.entity.player.burp": null, + "subtitles.entity.player.death": null, + "subtitles.entity.player.hurt": null, + "subtitles.entity.player.levelup": null, + "subtitles.entity.polar_bear.ambient": null, "subtitles.entity.polar_bear.baby_ambient": "subtitles.entity.polar_bear.ambient_baby", + "subtitles.entity.polar_bear.death": null, + "subtitles.entity.polar_bear.hurt": null, + "subtitles.entity.polar_bear.warning": null, + "subtitles.entity.potion.splash": null, + "subtitles.entity.potion.throw": null, + "subtitles.entity.rabbit.ambient": null, + "subtitles.entity.rabbit.attack": null, + "subtitles.entity.rabbit.death": null, + "subtitles.entity.rabbit.hurt": null, + "subtitles.entity.rabbit.jump": null, + "subtitles.entity.sheep.ambient": null, + "subtitles.entity.sheep.death": null, + "subtitles.entity.sheep.hurt": null, + "subtitles.entity.shulker.ambient": null, "subtitles.entity.shulker.close": "subtitles.block.shulker_box.close", + "subtitles.entity.shulker.death": null, + "subtitles.entity.shulker.hurt": null, "subtitles.entity.shulker.open": "subtitles.block.shulker_box.open", + "subtitles.entity.shulker.shoot": null, + "subtitles.entity.shulker.teleport": null, + "subtitles.entity.shulker_bullet.hit": null, + "subtitles.entity.shulker_bullet.hurt": null, + "subtitles.entity.silverfish.ambient": null, + "subtitles.entity.silverfish.death": null, + "subtitles.entity.silverfish.hurt": null, + "subtitles.entity.skeleton.ambient": null, + "subtitles.entity.skeleton.death": null, + "subtitles.entity.skeleton.hurt": null, + "subtitles.entity.skeleton.shoot": null, + "subtitles.entity.skeleton_horse.ambient": null, + "subtitles.entity.skeleton_horse.death": null, + "subtitles.entity.skeleton_horse.hurt": null, + "subtitles.entity.slime.attack": null, + "subtitles.entity.slime.death": null, + "subtitles.entity.slime.hurt": null, + "subtitles.entity.slime.squish": null, + "subtitles.entity.snowball.throw": null, "subtitles.entity.snowman.death": "subtitles.entity.snow_golem.death", "subtitles.entity.snowman.hurt": "subtitles.entity.snow_golem.hurt", + "subtitles.entity.spider.ambient": null, + "subtitles.entity.spider.death": null, + "subtitles.entity.spider.hurt": null, + "subtitles.entity.squid.ambient": null, + "subtitles.entity.squid.death": null, + "subtitles.entity.squid.hurt": null, + "subtitles.entity.stray.ambient": null, + "subtitles.entity.stray.death": null, + "subtitles.entity.stray.hurt": null, + "subtitles.entity.tnt.primed": null, + "subtitles.entity.vex.ambient": null, + "subtitles.entity.vex.charge": null, + "subtitles.entity.vex.death": null, + "subtitles.entity.vex.hurt": null, + "subtitles.entity.villager.ambient": null, + "subtitles.entity.villager.death": null, + "subtitles.entity.villager.hurt": null, + "subtitles.entity.villager.no": null, "subtitles.entity.villager.trading": "subtitles.entity.villager.trade", + "subtitles.entity.villager.yes": null, "subtitles.entity.vindication_illager.ambient": "subtitles.entity.vindicator.ambient", "subtitles.entity.vindication_illager.death": "subtitles.entity.vindicator.death", "subtitles.entity.vindication_illager.hurt": "subtitles.entity.vindicator.hurt", + "subtitles.entity.witch.ambient": null, + "subtitles.entity.witch.death": null, + "subtitles.entity.witch.drink": null, + "subtitles.entity.witch.hurt": null, + "subtitles.entity.witch.throw": null, + "subtitles.entity.wither.ambient": null, + "subtitles.entity.wither.death": null, + "subtitles.entity.wither.hurt": null, + "subtitles.entity.wither.shoot": null, + "subtitles.entity.wither.spawn": null, + "subtitles.entity.wither_skeleton.ambient": null, + "subtitles.entity.wither_skeleton.death": null, + "subtitles.entity.wither_skeleton.hurt": null, + "subtitles.entity.wolf.ambient": null, + "subtitles.entity.wolf.death": null, + "subtitles.entity.wolf.growl": null, + "subtitles.entity.wolf.hurt": null, + "subtitles.entity.wolf.shake": null, + "subtitles.entity.zombie.ambient": null, + "subtitles.entity.zombie.death": null, + "subtitles.entity.zombie.hurt": null, + "subtitles.entity.zombie.infect": null, + "subtitles.entity.zombie_horse.ambient": null, + "subtitles.entity.zombie_horse.death": null, + "subtitles.entity.zombie_horse.hurt": null, + "subtitles.entity.zombie_pigman.ambient": null, + "subtitles.entity.zombie_pigman.angry": null, + "subtitles.entity.zombie_pigman.death": null, + "subtitles.entity.zombie_pigman.hurt": null, + "subtitles.entity.zombie_villager.ambient": null, + "subtitles.entity.zombie_villager.converted": null, + "subtitles.entity.zombie_villager.cure": null, + "subtitles.entity.zombie_villager.death": null, + "subtitles.entity.zombie_villager.hurt": null, + "subtitles.item.armor.equip_chain": null, + "subtitles.item.armor.equip_diamond": null, + "subtitles.item.armor.equip_gold": null, + "subtitles.item.armor.equip_iron": null, + "subtitles.item.armor.equip_leather": null, + "subtitles.item.bottle.fill": null, + "subtitles.item.bucket.empty": null, + "subtitles.item.bucket.fill": null, + "subtitles.item.chorus_fruit.teleport": null, + "subtitles.item.firecharge.use": null, + "subtitles.item.flintandsteel.use": null, + "subtitles.item.hoe.till": null, "subtitles.item.shear": "subtitles.item.shears.shear", - "advancements.adventure.root.title": "selectWorld.gameMode.adventure" + "subtitles.item.shield.block": null, + "subtitles.item.shovel.flatten": null, + "subtitles.item.totem.use": null, + "subtitles.weather.rain": null, + "debug.prefix": null, + "debug.reload_chunks.message": null, + "debug.show_hitboxes.on": null, + "debug.show_hitboxes.off": null, + "debug.cycle_renderdistance.message": null, + "debug.chunk_boundaries.on": null, + "debug.chunk_boundaries.off": null, + "debug.advanced_tooltips.on": null, + "debug.advanced_tooltips.off": null, + "debug.creative_spectator.error": null, + "debug.pause_focus.on": null, + "debug.pause_focus.off": null, + "debug.help.message": null, + "debug.reload_resourcepacks.message": null, + "resourcepack.downloading": null, + "resourcepack.requesting": null, + "resourcepack.progress": null, + "tutorial.move.title": null, + "tutorial.move.description": null, + "tutorial.look.title": null, + "tutorial.look.description": null, + "tutorial.find_tree.title": null, + "tutorial.find_tree.description": null, + "tutorial.punch_tree.title": null, + "tutorial.punch_tree.description": null, + "tutorial.open_inventory.title": null, + "tutorial.open_inventory.description": null, + "tutorial.craft_planks.title": null, + "tutorial.craft_planks.description": null, + "advancements.adventure.adventuring_time.title": null, + "advancements.adventure.adventuring_time.description": null, + "advancements.adventure.kill_all_mobs.title": null, + "advancements.adventure.kill_all_mobs.description": null, + "advancements.adventure.kill_a_mob.title": null, + "advancements.adventure.kill_a_mob.description": null, + "advancements.adventure.root.title": "selectWorld.gameMode.adventure", + "advancements.adventure.root.description": null, + "advancements.adventure.shoot_arrow.title": null, + "advancements.adventure.shoot_arrow.description": null, + "advancements.adventure.sleep_in_bed.description": null, + "advancements.adventure.trade.title": null, + "advancements.adventure.trade.description": null, + "advancements.adventure.summon_iron_golem.title": null, + "advancements.adventure.summon_iron_golem.description": null, + "advancements.adventure.totem_of_undying.title": null, + "advancements.adventure.totem_of_undying.description": null, + "advancements.husbandry.root.title": null, + "advancements.husbandry.root.description": null, + "advancements.husbandry.breed_an_animal.title": null, + "advancements.husbandry.breed_an_animal.description": null, + "advancements.husbandry.breed_all_animals.title": null, + "advancements.husbandry.breed_all_animals.description": null, + "advancements.husbandry.tame_an_animal.title": null, + "advancements.husbandry.tame_an_animal.description": null, + "advancements.husbandry.plant_seed.title": null, + "advancements.husbandry.plant_seed.description": null, + "advancements.husbandry.break_diamond_hoe.title": null, + "advancements.husbandry.break_diamond_hoe.description": null, + "advancements.husbandry.balanced_diet.title": null, + "advancements.husbandry.balanced_diet.description": null, + "advancements.end.dragon_breath.title": null, + "advancements.end.dragon_breath.description": null, + "advancements.end.dragon_egg.title": null, + "advancements.end.dragon_egg.description": null, + "advancements.end.elytra.title": null, + "advancements.end.enter_end_gateway.title": null, + "advancements.end.enter_end_gateway.description": null, + "advancements.end.find_end_city.title": null, + "advancements.end.find_end_city.description": null, + "advancements.end.kill_dragon.title": null, + "advancements.end.kill_dragon.description": null, + "advancements.end.levitate.title": null, + "advancements.end.levitate.description": null, + "advancements.end.respawn_dragon.title": null, + "advancements.end.root.title": null, + "advancements.end.root.description": null, + "advancements.nether.brew_potion.title": null, + "advancements.nether.brew_potion.description": null, + "advancements.nether.all_potions.title": null, + "advancements.nether.all_potions.description": null, + "advancements.nether.all_effects.title": null, + "advancements.nether.all_effects.description": null, + "advancements.nether.create_beacon.title": null, + "advancements.nether.create_beacon.description": null, + "advancements.nether.create_full_beacon.title": null, + "advancements.nether.create_full_beacon.description": null, + "advancements.nether.find_fortress.title": null, + "advancements.nether.find_fortress.description": null, + "advancements.nether.get_wither_skull.title": null, + "advancements.nether.obtain_blaze_rod.title": null, + "advancements.nether.obtain_blaze_rod.description": null, + "advancements.nether.return_to_sender.title": null, + "advancements.nether.return_to_sender.description": null, + "advancements.nether.root.title": null, + "advancements.nether.root.description": null, + "advancements.nether.summon_wither.title": null, + "advancements.nether.summon_wither.description": null, + "advancements.nether.fast_travel.title": null, + "advancements.nether.uneasy_alliance.title": null, + "advancements.story.cure_zombie_villager.title": null, + "advancements.story.deflect_arrow.title": null, + "advancements.story.deflect_arrow.description": null, + "advancements.story.enchant_item.title": null, + "advancements.story.enchant_item.description": null, + "advancements.story.enter_the_end.title": null, + "advancements.story.enter_the_end.description": null, + "advancements.story.enter_the_nether.title": null, + "advancements.story.enter_the_nether.description": null, + "advancements.story.follow_ender_eye.title": null, + "advancements.story.form_obsidian.title": null, + "advancements.story.form_obsidian.description": null, + "advancements.story.iron_tools.title": null, + "advancements.story.iron_tools.description": null, + "advancements.story.lava_bucket.title": null, + "advancements.story.lava_bucket.description": null, + "advancements.story.mine_diamond.title": null, + "advancements.story.mine_diamond.description": null, + "advancements.story.mine_stone.title": null, + "advancements.story.mine_stone.description": null, + "advancements.story.obtain_armor.title": null, + "advancements.story.obtain_armor.description": null, + "advancements.story.root.title": null, + "advancements.story.root.description": null, + "advancements.story.shiny_gear.title": null, + "advancements.story.shiny_gear.description": null, + "advancements.story.smelt_iron.title": null, + "advancements.story.smelt_iron.description": null, + "advancements.story.upgrade_tools.title": null, + "advancements.story.upgrade_tools.description": null } \ No newline at end of file From 4c07b6d28d9ee5d0584713a8100c307d03873478 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sun, 30 Sep 2018 10:30:34 -0300 Subject: [PATCH 12/24] Squash Velocity platform commits incomplete velocity code untested velocity version detector update velocity module version Injecting, but not working facepalm Fix handler type Should work now will it work now? it works!!! fix npe in command tab completion Do not forward command to server implement server changing with different versions thanks @Leymooo Fix memory leaks maybe cleaner code? trying to port mainhandpatch, added todo fix version Use separated protocol version, add todo Trying to mitigate UserConnection#toServer concurrent issue port elytrapatch it works but horribly and needs a modification in velocity replace with a semaphore and EventLoop#submit Lock for incoming packets fix version remove some TODOs Listen to DisconnectEvent Relocate snakeyaml --- .../bukkit/platform/BukkitConfigAPI.java | 2 +- .../bungee/platform/BungeeConfigAPI.java | 2 +- common/pom.xml | 2 +- .../ViaVersion/api/data/UserConnection.java | 10 +- .../commands/ViaCommandHandler.java | 2 +- .../myles/ViaVersion/util/PipelineUtil.java | 19 ++ .../resources/assets/viaversion/config.yml | 22 ++ jar/pom.xml | 9 + pom.xml | 1 + .../sponge/platform/SpongeConfigAPI.java | 2 +- velocity/pom.xml | 62 ++++ .../ViaVersion/velocity/VersionInfo.java | 5 + .../us/myles/ViaVersion/VelocityPlugin.java | 203 +++++++++++++ .../command/VelocityCommandHandler.java | 29 ++ .../command/VelocityCommandSender.java | 46 +++ .../velocity/command/subs/ProbeSubCmd.java | 28 ++ .../handlers/VelocityChannelInitializer.java | 38 +++ .../handlers/VelocityDecodeHandler.java | 78 +++++ .../handlers/VelocityEncodeHandler.java | 90 ++++++ .../handlers/VelocityServerHandler.java | 138 +++++++++ .../velocity/listeners/ElytraPatch.java | 44 +++ .../velocity/listeners/MainHandPatch.java | 49 ++++ .../velocity/listeners/UpdateListener.java | 16 + .../velocity/platform/VelocityBossBar.java | 13 + .../velocity/platform/VelocityTaskId.java | 12 + .../velocity/platform/VelocityViaAPI.java | 78 +++++ .../velocity/platform/VelocityViaConfig.java | 275 ++++++++++++++++++ .../platform/VelocityViaInjector.java | 41 +++ .../velocity/platform/VelocityViaLoader.java | 45 +++ .../providers/VelocityBossBarProvider.java | 30 ++ .../VelocityMovementTransmitter.java | 35 +++ .../providers/VelocityVersionProvider.java | 73 +++++ .../service/ProtocolDetectorService.java | 82 ++++++ .../velocity/storage/VelocityStorage.java | 38 +++ .../velocity/util/LoggerWrapper.java | 69 +++++ 35 files changed, 1680 insertions(+), 8 deletions(-) create mode 100644 velocity/pom.xml create mode 100644 velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java index b033cdb79..74db3b715 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Map; public class BukkitConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers"); + private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); public BukkitConfigAPI() { super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml")); diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java index 1c013f3f2..4f9112099 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java @@ -10,7 +10,7 @@ import java.net.URL; import java.util.*; public class BungeeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix"); + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); public BungeeConfigAPI(File configFile) { super(new File(configFile, "config.yml")); diff --git a/common/pom.xml b/common/pom.xml index d1cad3b92..351079c5d 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -17,7 +17,7 @@ org.yaml snakeyaml 1.18 - provided + compile \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java index aa9019262..a620c3798 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java @@ -18,6 +18,8 @@ import us.myles.ViaVersion.util.PipelineUtil; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; @Data public class UserConnection { @@ -36,7 +38,7 @@ public class UserConnection { // Used for handling warnings (over time) private int secondsObserved = 0; private int warnings = 0; - + private ReadWriteLock velocityLock = new ReentrantReadWriteLock(); public UserConnection(Channel channel) { this.channel = channel; @@ -108,7 +110,8 @@ public class UserConnection { */ public ChannelFuture sendRawPacketFuture(final ByteBuf packet) { final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName()); - return channel.pipeline().context(handler).writeAndFlush(packet); + ChannelFuture future = channel.pipeline().context(handler).writeAndFlush(packet); + return future; } /** @@ -218,7 +221,8 @@ public class UserConnection { } buf.writeBytes(packet); packet.release(); - final ChannelHandlerContext context = PipelineUtil.getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline()); + final ChannelHandlerContext context = PipelineUtil + .getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline()); if (currentThread) { if (context != null) { context.fireChannelRead(buf); diff --git a/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java index c6afc0b6e..5610e2a50 100644 --- a/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java @@ -74,7 +74,7 @@ public abstract class ViaCommandHandler implements ViaVersionCommand { //SubCommands tabcomplete if (args.length == 1) { - if (!args[0].equals("")) { + if (!args[0].isEmpty()) { for (ViaSubCommand sub : allowed) if (sub.name().toLowerCase().startsWith(args[0].toLowerCase())) output.add(sub.name()); diff --git a/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java b/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java index f5bdd51f9..6be8ac0b8 100644 --- a/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java +++ b/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java @@ -5,6 +5,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.MessageToMessageEncoder; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -14,6 +16,7 @@ import java.util.List; public class PipelineUtil { private static Method DECODE_METHOD; private static Method ENCODE_METHOD; + private static Method MTM_DECODE; static { try { @@ -28,6 +31,12 @@ public class PipelineUtil { } catch (NoSuchMethodException e) { e.printStackTrace(); } + try { + MTM_DECODE = MessageToMessageDecoder.class.getDeclaredMethod("decode", ChannelHandlerContext.class, Object.class, List.class); + MTM_DECODE.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } } /** @@ -66,6 +75,16 @@ public class PipelineUtil { } } + public static List callDecode(MessageToMessageDecoder decoder, ChannelHandlerContext ctx, Object msg) throws InvocationTargetException { + List output = new ArrayList<>(); + try { + MTM_DECODE.invoke(decoder, ctx, msg, output); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return output; + } + /** * Check if a stack trace contains a certain exception * diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index 0252d7ffa..7675a477f 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -46,6 +46,28 @@ bungee-ping-save: true bungee-servers: {} # #----------------------------------------------------------# +# VELOCITY OPTIONS # +#----------------------------------------------------------# +# +# Velocity allows you to have different server versions inside. +# Instead of you entering all the versions of these servers, we can ping them. +# +# What interval would you like us to ping at? (in seconds) +# Use -1 to disable. +velocity-ping-interval: 60 +# If the above is enabled, should we save the info to the config (in the section below) +velocity-ping-save: true +# To get a servers protocol, ViaVersion will do the following: +# Look for the server in the following section, then look for the last ping if velocity-ping is enabled +# otherwise use default. +# +# The format for the following is: +# servername: protocolversion +# You can find protocol ids on http://wiki.vg/Protocol_version_numbers +# It will fallback to the default option if none found. +velocity-servers: {} +# +#----------------------------------------------------------# # GLOBAL PACKET LIMITER # #----------------------------------------------------------# # diff --git a/jar/pom.xml b/jar/pom.xml index a9399516f..95b282a0a 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -57,6 +57,10 @@ org.javassist us.myles.viaversion.libs.javassist + + org.yaml.snakeyaml + us.myles.viaversion.libs.snakeyaml + @@ -92,6 +96,11 @@ viaversion-sponge ${project.parent.version} + + us.myles + viaversion-velocity + ${project.parent.version} + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 00c615f8a..137071b6e 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ bungee sponge sponge-legacy + velocity jar diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java index 86a98cef7..a216b0017 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.Optional; public class SpongeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "quick-move-action-fix"); + private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix"); private final PluginContainer pluginContainer; public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { diff --git a/velocity/pom.xml b/velocity/pom.xml new file mode 100644 index 000000000..232fc97a4 --- /dev/null +++ b/velocity/pom.xml @@ -0,0 +1,62 @@ + + + + viaversion-parent + us.myles + 1.6.1-18w43c + + 4.0.0 + + viaversion-velocity + + + 1.8 + 1.8 + + + + + velocity + https://repo.velocitypowered.com/snapshots + + + + + + + org.codehaus.mojo + templating-maven-plugin + 1.0.0 + + + filter-src + + filter-sources + + + + + + + + + + + us.myles + viaversion-common + ${project.parent.version} + provided + + + + + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + provided + + + + \ No newline at end of file diff --git a/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java b/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java new file mode 100644 index 000000000..4b189c863 --- /dev/null +++ b/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java @@ -0,0 +1,5 @@ +package us.myles.ViaVersion.velocity; + +public class VersionInfo { + public static final String VERSION = "${project.version}"; +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java new file mode 100644 index 000000000..d01d0e6c5 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -0,0 +1,203 @@ +package us.myles.ViaVersion; + +import com.google.gson.JsonObject; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.PluginContainer; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import lombok.Getter; +import net.kyori.text.serializer.ComponentSerializers; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import org.slf4j.Logger; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.command.ViaCommandSender; +import us.myles.ViaVersion.api.configuration.ConfigurationProvider; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.platform.TaskId; +import us.myles.ViaVersion.api.platform.ViaPlatform; +import us.myles.ViaVersion.dump.PluginInfo; +import us.myles.ViaVersion.util.GsonUtil; +import us.myles.ViaVersion.velocity.VersionInfo; +import us.myles.ViaVersion.velocity.command.VelocityCommandHandler; +import us.myles.ViaVersion.velocity.command.VelocityCommandSender; +import us.myles.ViaVersion.velocity.platform.*; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; +import us.myles.ViaVersion.velocity.util.LoggerWrapper; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +@Plugin( + id = "viaversion", + name = "ViaVersion", + version = VersionInfo.VERSION, + authors = {"_MylesC", "Matsv"}, + description = "Allow newer Minecraft versions to connect to an older server version.", + url = "https://viaversion.com" +) +@Getter +public class VelocityPlugin implements ViaPlatform { + @Inject + private ProxyServer proxy; + @Inject + public static ProxyServer PROXY; + @Inject + private Logger loggerslf4j; + private java.util.logging.Logger logger; + @Inject + @DataDirectory + private Path configDir; + private VelocityViaAPI api = new VelocityViaAPI(); + private VelocityViaConfig conf; + + @Subscribe + public void onProxyInit(ProxyInitializeEvent e) { + PROXY = proxy; + VelocityCommandHandler commandHandler = new VelocityCommandHandler(); + PROXY.getCommandManager().register(commandHandler, "viaver", "vvvelocity", "viaversion"); + conf = new VelocityViaConfig(configDir.toFile()); + logger = new LoggerWrapper(loggerslf4j); + Via.init(ViaManager.builder() + .platform(this) + .commandHandler(commandHandler) + .loader(new VelocityViaLoader()) + .injector(new VelocityViaInjector()).build()); + Via.getManager().init(); + } + + @Subscribe + public void onQuit(DisconnectEvent e) { + UserConnection userConnection = Via.getManager().getPortedPlayers().get(e.getPlayer().getUniqueId()); + if (userConnection != null) { + // Only remove if the connection is disconnected (eg. relogin) + if (userConnection.getChannel() == null || !userConnection.getChannel().isOpen()) { + Via.getManager().removePortedClient(e.getPlayer().getUniqueId()); + } + } + } + + @Override + public String getPlatformName() { + return "Velocity"; + } + + @Override + public String getPlatformVersion() { + return ProxyServer.class.getPackage().getImplementationVersion(); + } + + @Override + public String getPluginVersion() { + return VersionInfo.VERSION; + } + + @Override + public TaskId runAsync(Runnable runnable) { + return runSync(runnable); + } + + @Override + public TaskId runSync(Runnable runnable) { + return runSync(runnable, 0L); + } + + @Override + public TaskId runSync(Runnable runnable, Long ticks) { + return new VelocityTaskId( + PROXY.getScheduler() + .buildTask(this, runnable) + .delay(ticks * 50, TimeUnit.MILLISECONDS).schedule() + ); + } + + @Override + public TaskId runRepeatingSync(Runnable runnable, Long ticks) { + return new VelocityTaskId( + PROXY.getScheduler() + .buildTask(this, runnable) + .repeat(ticks * 50, TimeUnit.MILLISECONDS).schedule() + ); + } + + @Override + public void cancelTask(TaskId taskId) { + if (taskId instanceof VelocityTaskId) { + ((VelocityTaskId) taskId).getObject().cancel(); + } + } + + @Override + public ViaCommandSender[] getOnlinePlayers() { + return PROXY.getAllPlayers().stream() + .map(VelocityCommandSender::new) + .toArray(ViaCommandSender[]::new); + } + + @Override + public void sendMessage(UUID uuid, String message) { + PROXY.getPlayer(uuid).ifPresent(it -> it.sendMessage( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // Fixes links + ) + )); + } + + @Override + public boolean kickPlayer(UUID uuid, String message) { + return PROXY.getPlayer(uuid).map(it -> { + it.disconnect( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // ComponentSerializers.LEGACY is deprecated + ) + ); + return true; + }).orElse(false); + } + + @Override + public boolean isPluginEnabled() { + return true; + } + + @Override + public ConfigurationProvider getConfigurationProvider() { + return conf; + } + + @Override + public void onReload() { + + } + + @Override + public JsonObject getDump() { + JsonObject extra = new JsonObject(); + List plugins = new ArrayList<>(); + for (PluginContainer p : PROXY.getPluginManager().getPlugins()) { + plugins.add(new PluginInfo( + true, + p.getDescription().getName().orElse(p.getDescription().getId()), + p.getDescription().getVersion().orElse("Unknown Version"), + p.getInstance().isPresent() ? p.getInstance().get().getClass().getCanonicalName() : "Unknown", + p.getDescription().getAuthors() + )); + } + extra.add("plugins", GsonUtil.getGson().toJsonTree(plugins)); + extra.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds())); + return extra; + } + + @Override + public boolean isOldClientsAllowed() { + return true; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java new file mode 100644 index 000000000..9c23a01e5 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java @@ -0,0 +1,29 @@ +package us.myles.ViaVersion.velocity.command; + +import com.velocitypowered.api.command.Command; +import com.velocitypowered.api.command.CommandSource; +import org.checkerframework.checker.nullness.qual.NonNull; +import us.myles.ViaVersion.commands.ViaCommandHandler; +import us.myles.ViaVersion.velocity.command.subs.ProbeSubCmd; + +import java.util.List; + +public class VelocityCommandHandler extends ViaCommandHandler implements Command { + public VelocityCommandHandler() { + try { + registerSubCommand(new ProbeSubCmd()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void execute(@NonNull CommandSource source, String[] args) { + onCommand(new VelocityCommandSender(source), args); + } + + @Override + public List suggest(@NonNull CommandSource source, String[] currentArgs) { + return onTabComplete(new VelocityCommandSender(source), currentArgs); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java new file mode 100644 index 000000000..1a61f8b5c --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java @@ -0,0 +1,46 @@ +package us.myles.ViaVersion.velocity.command; + +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.proxy.Player; +import lombok.AllArgsConstructor; +import net.kyori.text.serializer.ComponentSerializers; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import us.myles.ViaVersion.api.command.ViaCommandSender; + +import java.util.UUID; + +@AllArgsConstructor +public class VelocityCommandSender implements ViaCommandSender { + private CommandSource source; + + @Override + public boolean hasPermission(String permission) { + return source.hasPermission(permission); + } + + @Override + public void sendMessage(String msg) { + source.sendMessage( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(msg)) // Fixes links + ) + ); + } + + @Override + public UUID getUUID() { + if (source instanceof Player) { + return ((Player) source).getUniqueId(); + } + return UUID.fromString(getName()); + } + + @Override + public String getName() { + if (source instanceof Player) { + return ((Player) source).getUsername(); + } + return "?"; // :( + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java new file mode 100644 index 000000000..1470f49f1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java @@ -0,0 +1,28 @@ +package us.myles.ViaVersion.velocity.command.subs; + +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.command.ViaCommandSender; +import us.myles.ViaVersion.api.command.ViaSubCommand; +import us.myles.ViaVersion.velocity.platform.VelocityViaConfig; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; + +public class ProbeSubCmd extends ViaSubCommand { + @Override + public String name() { + return "probe"; + } + + @Override + public String description() { + return "Forces ViaVersion to scan server protocol versions " + + (((VelocityViaConfig) Via.getConfig()).getVelocityPingInterval() == -1 ? + "" : "(Also happens at an interval)"); + } + + @Override + public boolean execute(ViaCommandSender sender, String[] args) { + ProtocolDetectorService.getInstance().run(); + sendMessage(sender, "&6Started searching for protocol versions"); + return true; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java new file mode 100644 index 000000000..306bcf667 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java @@ -0,0 +1,38 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolPipeline; + +import java.lang.reflect.Method; + +@RequiredArgsConstructor +public class VelocityChannelInitializer extends ChannelInitializer { + @NonNull + private ChannelInitializer original; + private Method initChannel; + + { + try { + initChannel = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class); + initChannel.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + + @Override + protected void initChannel(Channel channel) throws Exception { + initChannel.invoke(original, channel); + + UserConnection user = new UserConnection(channel); + new ProtocolPipeline(user); + + // We need to add a separated handler because Velocity uses pipeline().get(MINECRAFT_DECODER) + channel.pipeline().addBefore("minecraft-encoder", "via-encoder", new VelocityEncodeHandler(user)); + channel.pipeline().addBefore("minecraft-decoder", "via-decoder", new VelocityDecodeHandler(user)); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java new file mode 100644 index 000000000..23dbd77fd --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java @@ -0,0 +1,78 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import lombok.AllArgsConstructor; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.exception.CancelException; +import us.myles.ViaVersion.packets.Direction; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.util.PipelineUtil; + +import java.util.List; + +@ChannelHandler.Sharable +@AllArgsConstructor +public class VelocityDecodeHandler extends MessageToMessageDecoder { + private final UserConnection info; + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception { + // use transformers + if (bytebuf.readableBytes() > 0) { + // Ignore if pending disconnect + if (info.isPendingDisconnect()) { + return; + } + // Increment received + boolean second = info.incrementReceived(); + // Check PPS + if (second) { + if (info.handlePPS()) + return; + } + info.getVelocityLock().readLock().lock(); + if (info.isActive()) { + // Handle ID + int id = Type.VAR_INT.read(bytebuf); + // Transform + ByteBuf newPacket = ctx.alloc().buffer(); + try { + if (id == PacketWrapper.PASSTHROUGH_ID) { + newPacket.writeBytes(bytebuf); + } else { + PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info); + ProtocolInfo protInfo = info.get(ProtocolInfo.class); + protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper); + wrapper.writeToBuffer(newPacket); + } + + bytebuf.clear(); + bytebuf = newPacket; + } catch (Exception e) { + // Clear Buffer + bytebuf.clear(); + // Release Packet, be free! + newPacket.release(); + info.getVelocityLock().readLock().unlock(); + throw e; + } + } else { + bytebuf.retain(); + } + info.getVelocityLock().readLock().unlock(); + + out.add(bytebuf); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelException.class)) return; + super.exceptionCaught(ctx, cause); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java new file mode 100644 index 000000000..1a929c2e8 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java @@ -0,0 +1,90 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.MessageToMessageEncoder; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.exception.CancelException; +import us.myles.ViaVersion.packets.Direction; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.util.PipelineUtil; + +import java.util.List; + +@ChannelHandler.Sharable +@RequiredArgsConstructor +public class VelocityEncodeHandler extends MessageToMessageEncoder { + @NonNull + private final UserConnection info; + private boolean handledCompression = false; + + @Override + protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception { + if (bytebuf.readableBytes() == 0) { + throw new CancelException(); + } + boolean needsCompress = false; + if (!handledCompression + && ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) { + // Need to decompress this packet due to bad order + bytebuf = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder) ctx.pipeline().get("compression-decoder"), ctx, bytebuf).get(0); + ChannelHandler encoder = ctx.pipeline().get("via-encoder"); + ChannelHandler decoder = ctx.pipeline().get("via-decoder"); + ctx.pipeline().remove(encoder); + ctx.pipeline().remove(decoder); + ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder); + ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder); + needsCompress = true; + handledCompression = true; + } else { + bytebuf.retain(); + } + // Increment sent + info.incrementSent(); + + + if (info.isActive()) { + // Handle ID + int id = Type.VAR_INT.read(bytebuf); + // Transform + ByteBuf newPacket = bytebuf.alloc().buffer(); + try { + PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info); + ProtocolInfo protInfo = info.get(ProtocolInfo.class); + protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper); + + wrapper.writeToBuffer(newPacket); + + bytebuf.clear(); + bytebuf.release(); + bytebuf = newPacket; + } catch (Exception e) { + bytebuf.clear(); + bytebuf.release(); + newPacket.release(); + throw e; + } + } + + if (needsCompress) { + ByteBuf old = bytebuf; + bytebuf = ctx.alloc().buffer(); + PipelineUtil.callEncode((MessageToByteEncoder) ctx.pipeline().get("compression-encoder"), ctx, old, bytebuf); + old.release(); + } + out.add(bytebuf); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelException.class)) return; + super.exceptionCaught(ctx, cause); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java new file mode 100644 index 000000000..51bb600d1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java @@ -0,0 +1,138 @@ +package us.myles.ViaVersion.velocity.handlers; + +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.event.player.ServerPreConnectEvent; +import us.myles.ViaVersion.api.Pair; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.boss.BossBar; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.Protocol; +import us.myles.ViaVersion.api.protocol.ProtocolPipeline; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; +import us.myles.ViaVersion.velocity.storage.VelocityStorage; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.concurrent.Semaphore; + +public class VelocityServerHandler { + private static Method setProtocolVersion; + private static Method setNextProtocolVersion; + + static { + try { + setProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setProtocolVersion", int.class); + setNextProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setNextProtocolVersion", int.class); + } catch (NoSuchMethodException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + + @Subscribe + public void preServerConnect(ServerPreConnectEvent e) { + try { + UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId()); + if (user == null) return; + if (!user.has(VelocityStorage.class)) { + user.put(new VelocityStorage(user, e.getPlayer())); + } + + int protocolId = ProtocolDetectorService.getProtocolId(e.getOriginalServer().getServerInfo().getName()); + List> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId); + + // Check if ViaVersion can support that version + Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection"); + setNextProtocolVersion.invoke(connection, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId); + + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e1) { + e1.printStackTrace(); + } + } + + @Subscribe(order = PostOrder.LATE) + public void connectedEvent(ServerConnectedEvent e) { + UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId()); + try { + checkServerChange(e, Via.getManager().getConnection(e.getPlayer().getUniqueId())); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { + if (user == null) return; + // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) + if (user.has(EntityTracker.class)) { + EntityTracker tracker = user.get(EntityTracker.class); + + if (tracker.getBossBarMap() != null) + for (BossBar bar : tracker.getBossBarMap().values()) + bar.hide(); + } + // Handle server/version change + if (user.has(VelocityStorage.class)) { + // Wait all the scheduled packets be sent + Semaphore semaphore = new Semaphore(1); + semaphore.acquireUninterruptibly(); + user.getChannel().eventLoop().submit((Runnable) semaphore::release); + semaphore.acquireUninterruptibly(); + semaphore.release(); + + user.getVelocityLock().writeLock().lock(); + + VelocityStorage storage = user.get(VelocityStorage.class); + + if (e.getServer() != null) { + if (!e.getServer().getServerInfo().getName().equals(storage.getCurrentServer())) { + String serverName = e.getServer().getServerInfo().getName(); + + storage.setCurrentServer(serverName); + + int protocolId = ProtocolDetectorService.getProtocolId(serverName); + + ProtocolInfo info = user.get(ProtocolInfo.class); + + // Refresh the pipes + List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId); + ProtocolPipeline pipeline = user.get(ProtocolInfo.class).getPipeline(); + user.clearStoredObjects(); + pipeline.cleanPipes(); + if (protocols == null) { + // TODO Check Bungee Supported Protocols? *shrugs* + protocolId = info.getProtocolVersion(); + } else { + for (Pair prot : protocols) { + pipeline.add(prot.getValue()); + } + } + + info.setServerProtocolVersion(protocolId); + // Add version-specific base Protocol + pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId)); + + user.put(info); + user.put(storage); + + user.setActive(protocols != null); + + // Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist. + for (Protocol protocol : pipeline.pipes()) { + protocol.init(user); + } + + Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection"); + int version = (int) ReflectionUtil.invoke(connection,"getNextProtocolVersion"); + setProtocolVersion.invoke(ReflectionUtil.invoke(e.getPlayer(), "getConnection"), version); + } + } + user.getVelocityLock().writeLock().unlock(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java new file mode 100644 index 000000000..9e9a93ba0 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java @@ -0,0 +1,44 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.api.type.types.version.Types1_9; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; + +import java.util.Collections; + +/* + * This patches https://github.com/MylesIsCool/ViaVersion/issues/555 + */ +public class ElytraPatch { + + @Subscribe(order = PostOrder.LAST) + public void onServerConnected(ServerConnectedEvent event) { + UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId()); + if (user == null) return; + + try { + if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { + int entityId = user.get(EntityTracker.class).getProvidedEntityId(); + + PacketWrapper wrapper = new PacketWrapper(0x39, null, user); + + wrapper.write(Type.VAR_INT, entityId); + wrapper.write(Types1_9.METADATA_LIST, Collections.singletonList(new Metadata(0, MetaType1_9.Byte, (byte) 0))); + + wrapper.send(Protocol1_9TO1_8.class); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java new file mode 100644 index 000000000..eae7f08c3 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java @@ -0,0 +1,49 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.proxy.player.PlayerSettings; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.Method; + +/* + This solves the wrong mainhand issue when you join with BungeeCord on a 1.8 server, and switch to a 1.9 or higher. + */ +public class MainHandPatch { + private static Method setSettings; + + static { + try { + Class clientSettings = Class.forName("com.velocitypowered.proxy.protocol.packet.ClientSettings"); + setSettings = Class.forName("com.velocitypowered.proxy.connection.client.ConnectedPlayer").getDeclaredMethod("setPlayerSettings", clientSettings); + setSettings.setAccessible(true); + } catch (ClassNotFoundException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + + @Subscribe + public void onServerConnect(ServerConnectedEvent event) { + UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId()); + if (user == null || setSettings == null) return; + + try { + if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { + PlayerSettings settings = event.getPlayer().getPlayerSettings(); + if (user.has(EntityTracker.class)) { + Object clientSettings = ReflectionUtil.get(settings, "settings", Object.class); + ReflectionUtil.set(clientSettings, "mainHand", user.get(EntityTracker.class).getMainHand()); + setSettings.invoke(event.getPlayer(), clientSettings); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java new file mode 100644 index 000000000..d12069810 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java @@ -0,0 +1,16 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.update.UpdateUtil; + +public class UpdateListener { + @Subscribe + public void onJoin(PostLoginEvent e) { + if (e.getPlayer().hasPermission("viaversion.update") + && Via.getConfig().isCheckForUpdates()) { + UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId()); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java new file mode 100644 index 000000000..46a767c6a --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java @@ -0,0 +1,13 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.proxy.Player; +import us.myles.ViaVersion.api.boss.BossBar; +import us.myles.ViaVersion.api.boss.BossColor; +import us.myles.ViaVersion.api.boss.BossStyle; +import us.myles.ViaVersion.boss.CommonBoss; + +public class VelocityBossBar extends CommonBoss { + public VelocityBossBar(String title, float health, BossColor color, BossStyle style) { + super(title, health, color, style); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java new file mode 100644 index 000000000..9d7edbb56 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java @@ -0,0 +1,12 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.scheduler.ScheduledTask; +import lombok.AllArgsConstructor; +import lombok.Getter; +import us.myles.ViaVersion.api.platform.TaskId; + +@Getter +@AllArgsConstructor +public class VelocityTaskId implements TaskId { + private ScheduledTask object; +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java new file mode 100644 index 000000000..aca7fe39a --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java @@ -0,0 +1,78 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.proxy.Player; +import io.netty.buffer.ByteBuf; +import lombok.NonNull; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.ViaAPI; +import us.myles.ViaVersion.api.boss.BossBar; +import us.myles.ViaVersion.api.boss.BossColor; +import us.myles.ViaVersion.api.boss.BossStyle; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; + +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.UUID; + +public class VelocityViaAPI implements ViaAPI { + @Override + public int getPlayerVersion(@NonNull Player player) { + if (!isPorted(player.getUniqueId())) + return ProtocolRegistry.SERVER_PROTOCOL; + return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion(); + } + + @Override + public int getPlayerVersion(@NonNull UUID uuid) { + if (!isPorted(uuid)) + return ProtocolRegistry.SERVER_PROTOCOL; + return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion(); + } + + @Override + public boolean isPorted(UUID playerUUID) { + return getPortedPlayers().containsKey(playerUUID); + } + + @Override + public String getVersion() { + return Via.getPlatform().getPluginVersion(); + } + + @Override + public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException { + if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!"); + UserConnection ci = getPortedPlayers().get(uuid); + ci.sendRawPacket(packet); + } + + @Override + public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException { + sendRawPacket(player.getUniqueId(), packet); + } + + @Override + public BossBar createBossBar(String title, BossColor color, BossStyle style) { + return new VelocityBossBar(title, 1F, color, style); + } + + @Override + public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) { + return new VelocityBossBar(title, health, color, style); + } + + @Override + public SortedSet getSupportedVersions() { + SortedSet outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions()); + outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols()); + + return outputSet; + } + + public Map getPortedPlayers() { + return Via.getManager().getPortedPlayers(); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java new file mode 100644 index 000000000..373bd5c61 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java @@ -0,0 +1,275 @@ +package us.myles.ViaVersion.velocity.platform; + +import us.myles.ViaVersion.api.ViaVersionConfig; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.util.Config; + +import java.io.File; +import java.net.URL; +import java.util.*; + +public class VelocityViaConfig extends Config implements ViaVersionConfig { + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "bungee-ping-interval", "bungee-ping-save", "bungee-servers"); + + public VelocityViaConfig(File configFile) { + super(new File(configFile, "config.yml")); + // Load config + reloadConfig(); + } + + @Override + public URL getDefaultConfigURL() { + return getClass().getClassLoader().getResource("assets/viaversion/config.yml"); + } + + @Override + protected void handleConfig(Map config) { + // Parse servers + Map servers; + if (!(config.get("velocity-servers") instanceof Map)) { + servers = new HashMap<>(); + } else { + servers = (Map) config.get("velocity-servers"); + } + // Convert any bad Protocol Ids + for (Map.Entry entry : new HashSet<>(servers.entrySet())) { + if (!(entry.getValue() instanceof Integer)) { + if (entry.getValue() instanceof String) { + ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue()); + if (found != null) { + servers.put(entry.getKey(), found.getId()); + } else { + servers.remove(entry.getKey()); // Remove! + } + } else { + servers.remove(entry.getKey()); // Remove! + } + } + } + // Ensure default exists + if (!servers.containsKey("default")) { + servers.put("default", ProtocolRegistry.SERVER_PROTOCOL); + } + // Put back + config.put("velocity-servers", servers); + } + + @Override + public List getUnsupportedOptions() { + return UNSUPPORTED; + } + + public boolean isCheckForUpdates() { + return getBoolean("checkforupdates", true); + } + + @Override + public boolean isPreventCollision() { + return getBoolean("prevent-collision", true); + } + + @Override + public boolean isNewEffectIndicator() { + return getBoolean("use-new-effect-indicator", true); + } + + @Override + public boolean isShowNewDeathMessages() { + return getBoolean("use-new-deathmessages", true); + } + + @Override + public boolean isSuppressMetadataErrors() { + return getBoolean("suppress-metadata-errors", false); + } + + @Override + public boolean isShieldBlocking() { + return getBoolean("shield-blocking", true); + } + + @Override + public boolean isHologramPatch() { + return getBoolean("hologram-patch", false); + } + + @Override + public boolean isPistonAnimationPatch() { + return getBoolean("piston-animation-patch", false); + } + + @Override + public boolean isBossbarPatch() { + return getBoolean("bossbar-patch", true); + } + + @Override + public boolean isBossbarAntiflicker() { + return getBoolean("bossbar-anti-flicker", false); + } + + @Override + public boolean isUnknownEntitiesSuppressed() { + return false; + } + + @Override + public double getHologramYOffset() { + return getDouble("hologram-y", -0.96D); + } + + @Override + public boolean isBlockBreakPatch() { + return false; + } + + @Override + public int getMaxPPS() { + return getInt("max-pps", 800); + } + + @Override + public String getMaxPPSKickMessage() { + return getString("max-pps-kick-msg", "Sending packets too fast? lag?"); + } + + @Override + public int getTrackingPeriod() { + return getInt("tracking-period", 6); + } + + @Override + public int getWarningPPS() { + return getInt("tracking-warning-pps", 120); + } + + @Override + public int getMaxWarnings() { + return getInt("tracking-max-warnings", 3); + } + + @Override + public String getMaxWarningsKickMessage() { + return getString("tracking-max-kick-msg", "You are sending too many packets, :("); + } + + @Override + public boolean isAntiXRay() { + return false; + } + + @Override + public boolean isSendSupportedVersions() { + return getBoolean("send-supported-versions", false); + } + + @Override + public boolean isStimulatePlayerTick() { + return getBoolean("simulate-pt", true); + } + + @Override + public boolean isItemCache() { + return false; + } + + @Override + public boolean isNMSPlayerTicking() { + return false; + } + + @Override + public boolean isReplacePistons() { + return getBoolean("replace-pistons", false); + } + + @Override + public int getPistonReplacementId() { + return getInt("replacement-piston-id", 0); + } + + public boolean isAutoTeam() { + // Collision has to be enabled first + return isPreventCollision() && getBoolean("auto-team", true); + } + + @Override + public boolean isForceJsonTransform() { + return getBoolean("force-json-transform", false); + } + + @Override + public boolean is1_12NBTArrayFix() { + return getBoolean("chat-nbt-fix", true); + } + + @Override + public boolean is1_12QuickMoveActionFix() { + return false; + } + + @Override + public List getBlockedProtocols() { + return getIntegerList("block-protocols"); + } + + @Override + public String getBlockedDisconnectMsg() { + return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!"); + } + + @Override + public String getReloadDisconnectMsg() { + return getString("reload-disconnect-msg", "Server reload, please rejoin!"); + } + + @Override + public boolean isMinimizeCooldown() { + return getBoolean("minimize-cooldown", true); + } + + /** + * What is the interval for checking servers via ping + * -1 for disabled + * + * @return Ping interval in seconds + */ + public int getVelocityPingInterval() { + return getInt("velocity-ping-interval", 60); + } + + /** + * Should the velocity ping be saved to the config on change. + * + * @return True if it should save + */ + public boolean isVelocityPingSave() { + return getBoolean("velocity-ping-save", true); + } + + /** + * Get the listed server protocols in the config. + * default will be listed as default. + * + * @return Map of String, Integer + */ + public Map getVelocityServerProtocols() { + return get("velocity-servers", Map.class, new HashMap<>()); + } + + @Override + public boolean is1_13TeamColourFix() { + return getBoolean("team-colour-fix", true); + } + + @Override + public boolean isSuppress1_13ConversionErrors() { + return getBoolean("suppress-1_13-conversion-errors", false); + } + + @Override + public boolean isDisable1_13AutoComplete() { + return getBoolean("disable-1_13-auto-complete", false); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java new file mode 100644 index 000000000..78e5a532b --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java @@ -0,0 +1,41 @@ +package us.myles.ViaVersion.velocity.platform; + +import io.netty.channel.ChannelInitializer; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.platform.ViaInjector; +import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion.velocity.handlers.VelocityChannelInitializer; + + +public class VelocityViaInjector implements ViaInjector { + @Override + public void inject() throws Exception { + Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class); + Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer"); + ChannelInitializer originalIntializer = (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get"); + channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class) + .invoke(channelInitializerHolder, new VelocityChannelInitializer(originalIntializer)); + } + + @Override + public void uninject() { + Via.getPlatform().getLogger().severe("ViaVersion cannot remove itself from Velocity without a reboot!"); + } + + + @Override + public int getServerProtocolVersion() throws Exception { + return ReflectionUtil.getStatic(Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), "MINIMUM_GENERIC_VERSION", int.class); + } + + @Override + public String getEncoderName() { + return "via-encoder"; + } + + @Override + public String getDecoderName() { + return "via-decoder"; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java new file mode 100644 index 000000000..ff2ff10f1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java @@ -0,0 +1,45 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.plugin.PluginContainer; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.platform.ViaPlatformLoader; +import us.myles.ViaVersion.protocols.base.VersionProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import us.myles.ViaVersion.velocity.handlers.VelocityServerHandler; +import us.myles.ViaVersion.velocity.listeners.ElytraPatch; +import us.myles.ViaVersion.velocity.listeners.MainHandPatch; +import us.myles.ViaVersion.velocity.listeners.UpdateListener; +import us.myles.ViaVersion.velocity.providers.VelocityBossBarProvider; +import us.myles.ViaVersion.velocity.providers.VelocityMovementTransmitter; +import us.myles.ViaVersion.velocity.providers.VelocityVersionProvider; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; + +public class VelocityViaLoader implements ViaPlatformLoader { + @Override + public void load() { + Object plugin = VelocityPlugin.PROXY.getPluginManager() + .getPlugin("viaversion").flatMap(PluginContainer::getInstance).get(); + + Via.getManager().getProviders().use(MovementTransmitterProvider.class, new VelocityMovementTransmitter()); + Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider()); + Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider()); + // We probably don't need a EntityIdProvider because velocity sends a Join packet on server change + + VelocityPlugin.PROXY.getEventManager().register( + plugin, + new UpdateListener()); + Via.getPlatform().runRepeatingSync( + new ProtocolDetectorService(), + ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval() * 50L); + VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler()); + VelocityPlugin.PROXY.getEventManager().register(plugin, new MainHandPatch()); + VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch()); + } + + @Override + public void unload() { + // Probably not useful, there's no ProxyReloadEvent + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java new file mode 100644 index 000000000..276d4b931 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java @@ -0,0 +1,30 @@ +package us.myles.ViaVersion.velocity.providers; + +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider; +import us.myles.ViaVersion.velocity.storage.VelocityStorage; + +import java.util.UUID; + +public class VelocityBossBarProvider extends BossBarProvider { + @Override + public void handleAdd(UserConnection user, UUID barUUID) { + if (user.has(VelocityStorage.class)) { + VelocityStorage storage = user.get(VelocityStorage.class); + // Check if bossbars are supported by bungee, static maybe + if (storage.getBossbar() != null) { + storage.getBossbar().add(barUUID); + } + } + } + + @Override + public void handleRemove(UserConnection user, UUID barUUID) { + if (user.has(VelocityStorage.class)) { + VelocityStorage storage = user.get(VelocityStorage.class); + if (storage.getBossbar() != null) { + storage.getBossbar().remove(barUUID); + } + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java new file mode 100644 index 000000000..473633790 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java @@ -0,0 +1,35 @@ +package us.myles.ViaVersion.velocity.providers; + +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; + +public class VelocityMovementTransmitter extends MovementTransmitterProvider { + @Override + public Object getFlyingPacket() { + return null; + } + + @Override + public Object getGroundPacket() { + return null; + } + + public void sendPlayer(UserConnection userConnection) { + if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) { + PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection); + wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround()); + try { + wrapper.sendToServer(Protocol1_9TO1_8.class); + } catch (Exception e) { + e.printStackTrace(); + } + // PlayerPackets will increment idle + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java new file mode 100644 index 000000000..30fd4add9 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java @@ -0,0 +1,73 @@ +package us.myles.ViaVersion.velocity.providers; + +import com.google.common.collect.Lists; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.base.VersionProvider; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class VelocityVersionProvider extends VersionProvider { + private static Class ref ; + + static { + try { + ref = Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"); + } catch (Exception e) { + Via.getPlatform().getLogger().severe("Could not detect the ProtocolConstants class"); + e.printStackTrace(); + } + } + + @Override + public int getServerProtocol(UserConnection user) throws Exception { + if (ref == null) + return super.getServerProtocol(user); + // TODO Have one constant list forever until restart? (Might limit plugins if they change this) + Object list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSIONS", Object.class); + List sorted = new ArrayList((List) ReflectionUtil.invoke(list, "asList")); + Collections.sort(sorted); + + ProtocolInfo info = user.get(ProtocolInfo.class); + + // Bungee supports it + if (sorted.contains(info.getProtocolVersion())) + return info.getProtocolVersion(); + + // Older than bungee supports, get the lowest version + if (info.getProtocolVersion() < sorted.get(0)) { + return getLowestSupportedVersion(); + } + + // Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too) + + // TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work. + // This is more of a workaround for snapshot support by bungee. + for (Integer protocol : Lists.reverse(sorted)) { + if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol)) + return protocol; + } + + Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + info.getProtocolVersion()); + return info.getProtocolVersion(); + } + + public static int getLowestSupportedVersion() { + List list; + try { + return ReflectionUtil.getStatic( + Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), + "MINIMUM_GENERIC_VERSION", + int.class); + } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) { + e.printStackTrace(); + } + // Fallback + return -1; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java new file mode 100644 index 000000000..8abe51927 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java @@ -0,0 +1,82 @@ +package us.myles.ViaVersion.velocity.service; + +import com.velocitypowered.api.proxy.server.RegisteredServer; +import lombok.Getter; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.velocity.platform.VelocityViaConfig; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ProtocolDetectorService implements Runnable { + private static final Map detectedProtocolIds = new ConcurrentHashMap<>(); + @Getter + private static ProtocolDetectorService instance; + + public ProtocolDetectorService() { + instance = this; + } + + public static Integer getProtocolId(String serverName) { + // Step 1. Check Config + Map servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols(); + Integer protocol = servers.get(serverName); + if (protocol != null) { + return protocol; + } + // Step 2. Check Detected + Integer detectedProtocol = detectedProtocolIds.get(serverName); + if (detectedProtocol != null) { + return detectedProtocol; + } + // Step 3. Use Default + Integer defaultProtocol = servers.get("default"); + if (defaultProtocol != null) { + return defaultProtocol; + } + // Step 4: Use bungee lowest supported... *cries* + try { + return Via.getManager().getInjector().getServerProtocolVersion(); + } catch (Exception e) { + e.printStackTrace(); + return ProtocolVersion.v1_8.getId(); + } + } + + @Override + public void run() { + for (final RegisteredServer serv : VelocityPlugin.PROXY.getAllServers()) { + probeServer(serv); + } + } + + public static void probeServer(final RegisteredServer serverInfo) { + final String key = serverInfo.getServerInfo().getName(); + serverInfo.ping().thenAccept((serverPing) -> { + if (serverPing != null && serverPing.getVersion() != null) { + detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); + if (((VelocityViaConfig) Via.getConfig()).isVelocityPingSave()) { + Map servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols(); + Integer protocol = servers.get(key); + if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { + return; + } + // Ensure we're the only ones writing to the config + synchronized (Via.getPlatform().getConfigurationProvider()) { + servers.put(key, serverPing.getVersion().getProtocol()); + } + // Save + Via.getPlatform().getConfigurationProvider().saveConfig(); + } + } + }); + } + + public static Map getDetectedIds() { + return new HashMap<>(detectedProtocolIds); + } + +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java new file mode 100644 index 000000000..353430070 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java @@ -0,0 +1,38 @@ +package us.myles.ViaVersion.velocity.storage; + +import com.velocitypowered.api.proxy.Player; +import lombok.Data; +import lombok.EqualsAndHashCode; +import us.myles.ViaVersion.api.data.StoredObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.InvocationTargetException; +import java.util.Set; +import java.util.UUID; + +@Data +@EqualsAndHashCode(callSuper = true) +public class VelocityStorage extends StoredObject { + private Player player; + private String currentServer; + private Set bossbar; + + public VelocityStorage(UserConnection user, Player player) { + super(user); + this.player = player; + this.currentServer = ""; + + // Get bossbar list if it's supported + try { + Object connection = ReflectionUtil.invoke(player, "getConnection"); + Object sessionHandler = ReflectionUtil.invoke(connection, "getSessionHandler"); + if (sessionHandler.getClass().getSimpleName().contains("Play")) { + bossbar = (Set) ReflectionUtil.invoke(sessionHandler, "getServerBossBars"); + // TODO make this work + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java new file mode 100644 index 000000000..60300e8c7 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java @@ -0,0 +1,69 @@ +package us.myles.ViaVersion.velocity.util; + +import org.slf4j.Logger; + +import java.text.MessageFormat; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +public class LoggerWrapper extends java.util.logging.Logger { + private final Logger base; + + public LoggerWrapper(Logger logger) { + super("logger", null); + this.base = logger; + } + + @Override + public void log(LogRecord record) { + log(record.getLevel(), record.getMessage()); + } + + @Override + public void log(Level level, String msg) { + if (level == Level.FINE) + base.debug(msg); + else if (level == Level.WARNING) + base.warn(msg); + else if (level == Level.SEVERE) + base.error(msg); + else if (level == Level.INFO) + base.info(msg); + else + base.trace(msg); + } + + @Override + public void log(Level level, String msg, Object param1) { + if (level == Level.FINE) + base.debug(msg, param1); + else if (level == Level.WARNING) + base.warn(msg, param1); + else if (level == Level.SEVERE) + base.error(msg, param1); + else if (level == Level.INFO) + base.info(msg, param1); + else + base.trace(msg, param1); + } + + @Override + public void log(Level level, String msg, Object[] params) { + log(level, MessageFormat.format(msg, params)); // workaround not formatting correctly + } + + @Override + public void log(Level level, String msg, Throwable params) { + if (level == Level.FINE) + base.debug(msg, params); + else if (level == Level.WARNING) + base.warn(msg, params); + else if (level == Level.SEVERE) + base.error(msg, params); + else if (level == Level.INFO) + base.info(msg, params); + else + base.trace(msg, params); + } + +} From 3ef1ac06df52a9c19e081fab5ffdbe898d6657bf Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Mon, 12 Nov 2018 14:21:48 -0200 Subject: [PATCH 13/24] fix version, detect velocity implementation, fix npe, fix detectorservice --- velocity/pom.xml | 2 +- .../java/us/myles/ViaVersion/VelocityPlugin.java | 6 ++++-- .../velocity/platform/VelocityViaLoader.java | 14 ++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/velocity/pom.xml b/velocity/pom.xml index 232fc97a4..50d9a28d5 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-18w43c + 1.6.1-SNAPSHOT 4.0.0 diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java index d01d0e6c5..f16cad720 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -87,12 +87,14 @@ public class VelocityPlugin implements ViaPlatform { @Override public String getPlatformName() { - return "Velocity"; + String proxyImpl = ProxyServer.class.getPackage().getImplementationTitle(); + return (proxyImpl != null) ? proxyImpl : "Velocity"; } @Override public String getPlatformVersion() { - return ProxyServer.class.getPackage().getImplementationVersion(); + String version = ProxyServer.class.getPackage().getImplementationVersion(); + return (version != null) ? version : "Unknown"; } @Override diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java index ff2ff10f1..f81447437 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java @@ -27,15 +27,17 @@ public class VelocityViaLoader implements ViaPlatformLoader { Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider()); // We probably don't need a EntityIdProvider because velocity sends a Join packet on server change - VelocityPlugin.PROXY.getEventManager().register( - plugin, - new UpdateListener()); - Via.getPlatform().runRepeatingSync( - new ProtocolDetectorService(), - ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval() * 50L); + VelocityPlugin.PROXY.getEventManager().register(plugin, new UpdateListener()); VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler()); VelocityPlugin.PROXY.getEventManager().register(plugin, new MainHandPatch()); VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch()); + + int pingInterval = ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval(); + if (pingInterval > 0) { + Via.getPlatform().runRepeatingSync( + new ProtocolDetectorService(), + pingInterval * 20L); + } } @Override From b86950d0e7fb7e8370eac80a7c7418127e1366ed Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Tue, 13 Nov 2018 10:59:11 +0100 Subject: [PATCH 14/24] fix #1076 --- .../protocol1_13_2to1_13_1/Protocol1_13_2To1_13_1.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_2to1_13_1/Protocol1_13_2To1_13_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_2to1_13_1/Protocol1_13_2To1_13_1.java index 0bc2d5534..19394f359 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_2to1_13_1/Protocol1_13_2To1_13_1.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_2to1_13_1/Protocol1_13_2To1_13_1.java @@ -26,8 +26,7 @@ public class Protocol1_13_2To1_13_1 extends Protocol { registerIncoming(State.PLAY, 0x0B, 0x0B, new PacketRemapper() { @Override public void registerMap() { - map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); - map(Type.BOOLEAN); + map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM); } }); From 14377ca3543ef7c9e5d8d0662d64fe6bd2503672 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Thu, 25 Oct 2018 13:56:40 +0200 Subject: [PATCH 15/24] Use types for ChunkSections --- .../api/minecraft/chunks/Chunk.java | 30 +- .../api/minecraft/chunks/ChunkSection.java | 179 +++++++-- .../types/version/ChunkSectionType1_13.java | 114 ++++++ .../types/version/ChunkSectionType1_8.java | 43 ++ .../types/version/ChunkSectionType1_9.java | 110 ++++++ .../api/type/types/version/Types1_13.java | 3 + .../api/type/types/version/Types1_8.java | 3 + .../api/type/types/version/Types1_9.java | 3 + .../chunks/Chunk1_13.java | 25 -- .../chunks/ChunkSection1_13.java | 311 --------------- .../packets/WorldPackets.java | 2 +- .../types/Chunk1_13Type.java | 12 +- .../chunks/Chunk1_9_3_4.java | 25 -- .../chunks/ChunkSection1_9_3_4.java | 368 ------------------ .../types/Chunk1_9_3_4Type.java | 12 +- .../chunks/Chunk1_9_1_2.java | 24 -- .../chunks/ChunkSection1_9_1_2.java | 360 ----------------- .../types/Chunk1_9_1_2Type.java | 12 +- .../chunks/Chunk1_9to1_8.java | 28 +- .../chunks/ChunkSection1_9to1_8.java | 263 ------------- .../packets/WorldPackets.java | 4 +- ...{ChunkType.java => Chunk1_9to1_8Type.java} | 47 +-- 22 files changed, 477 insertions(+), 1501 deletions(-) create mode 100644 common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java create mode 100644 common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java create mode 100644 common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java delete mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java rename common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/{ChunkType.java => Chunk1_9to1_8Type.java} (75%) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java index c17ed7f6f..67e2c188b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java @@ -1,23 +1,23 @@ package us.myles.ViaVersion.api.minecraft.chunks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import lombok.AllArgsConstructor; +import lombok.Data; import java.util.List; -public interface Chunk { - int getX(); +@Data +@AllArgsConstructor +public class Chunk { + protected int x; + protected int z; + protected boolean groundUp; + protected int bitmask; + protected ChunkSection[] sections; + protected byte[] biomeData; + protected List blockEntities; - int getZ(); - - ChunkSection[] getSections(); - - boolean isGroundUp(); - - boolean isBiomeData(); - - byte[] getBiomeData(); - - int getBitmask(); - - List getBlockEntities(); + public boolean isBiomeData() { + return biomeData != null; + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 0a6aa0274..2afdbc2cb 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -1,19 +1,32 @@ package us.myles.ViaVersion.api.minecraft.chunks; +import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import java.util.List; -public interface ChunkSection { +public class ChunkSection { /** - * Gets a block state id (< 1.13: block_id << 4 | data & 0xF) - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @return Block raw id + * Size (dimensions) of blocks in a chunks section. */ - int getBlock(int x, int y, int z); + public static final int SIZE = 16 * 16 * 16; // width * depth * height + /** + * Length of the sky and block light nibble arrays. + */ + public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) + /** + * Length of the block data array. + */ + private final List palette = Lists.newArrayList(); + private final int[] blocks; + private NibbleArray blockLight; + private NibbleArray skyLight; + + public ChunkSection() { + this.blocks = new int[SIZE]; + this.blockLight = new NibbleArray(SIZE); + palette.add(0); // AIR + } /** * Set a block in the chunks @@ -21,53 +34,149 @@ public interface ChunkSection { * @param x Block X * @param y Block Y * @param z Block Z - * @param type The block id + * @param type The type of the block * @param data The data value of the block */ - void setBlock(int x, int y, int z, int type, int data); + public void setBlock(int x, int y, int z, int type, int data) { + setFlatBlock(index(x, y, z), type << 4 | (data & 0xF)); + } + + public void setFlatBlock(int x, int y, int z, int type) { + setFlatBlock(index(x, y, z), type); + } + + public int getBlockId(int x, int y, int z) { + return getFlatBlock(x, y, z) >> 4; + } + + public int getBlockData(int x, int y, int z) { + return getFlatBlock(x, y, z) & 0xF; + } + + public int getFlatBlock(int x, int y, int z) { + int index = blocks[index(x, y, z)]; + return palette.get(index); + } + + public int getFlatBlock(int idx) { + int index = blocks[idx]; + return palette.get(index); + } + + public void setBlock(int idx, int type, int data) { + setFlatBlock(idx, type << 4 | (data & 0xF)); + } + + public void setPaletteIndex(int idx, int index) { + blocks[idx] = index; + } + + public int getPaletteIndex(int idx) { + return blocks[idx]; + } /** - * Set a block state in the chunk + * Set a block in the chunks based on the index * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param blockState The block state id + * @param idx Index + * @param id The raw or flat id of the block */ - void setFlatBlock(int x, int y, int z, int blockState); + public void setFlatBlock(int idx, int id) { + int index = palette.indexOf(id); + if (index == -1) { + index = palette.size(); + palette.add(id); + } + + blocks[idx] = index; + } /** - * Gets a block id (without data) - * /!\ YOU SHOULD NOT USE THIS ON 1.13 + * Set the block light array * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @return Block id (without data) + * @param data The value to set the block light to */ - int getBlockId(int x, int y, int z); + public void setBlockLight(byte[] data) { + if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); + if (this.blockLight == null) { + this.blockLight = new NibbleArray(data); + } else { + this.blockLight.setHandle(data); + } + } /** - * Write the blocks in < 1.13 format to a buffer. + * Set the sky light array * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. + * @param data The value to set the sky light to */ - void writeBlocks(ByteBuf output) throws Exception; + public void setSkyLight(byte[] data) { + if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); + if (this.skyLight == null) { + this.skyLight = new NibbleArray(data); + } else { + this.skyLight.setHandle(data); + } + } + + public byte[] getBlockLight() { + return blockLight == null ? null : blockLight.getHandle(); + } + + public byte[] getSkyLight() { + return skyLight == null ? null : skyLight.getHandle(); + } + + public void readBlockLight(ByteBuf input) { + if (this.blockLight == null) { + this.blockLight = new NibbleArray(LIGHT_LENGTH * 2); + } + input.readBytes(this.blockLight.getHandle()); + } + + public void readSkyLight(ByteBuf input) { + if (this.skyLight == null) { + this.skyLight = new NibbleArray(LIGHT_LENGTH * 2); + } + input.readBytes(this.skyLight.getHandle()); + } + + private static int index(int x, int y, int z) { + return y << 8 | z << 4 | x; + } /** - * Write the blocks in 1.13 format to a buffer. + * Write the block light to a buffer * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. + * @param output The buffer to write to */ - void writeBlocks1_13(ByteBuf output) throws Exception; + public void writeBlockLight(ByteBuf output) { + output.writeBytes(blockLight.getHandle()); + } - void writeBlockLight(ByteBuf output) throws Exception; + /** + * Write the sky light to a buffer + * + * @param output The buffer to write to + */ + public void writeSkyLight(ByteBuf output) { + output.writeBytes(skyLight.getHandle()); + } - boolean hasSkyLight(); + public List getPalette() { + return palette; + } - void writeSkyLight(ByteBuf output) throws Exception; + /** + * Check if sky light is present + * + * @return True if skylight is present + */ + public boolean hasSkyLight() { + return skyLight != null; + } - List getPalette(); + public boolean hasBlockLight() { + return blockLight != null; + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java new file mode 100644 index 000000000..ee6b89721 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java @@ -0,0 +1,114 @@ +package us.myles.ViaVersion.api.type.types.version; + +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.Type; + +import java.util.List; + +public class ChunkSectionType1_13 extends Type { + + public ChunkSectionType1_13() { + super("Chunk Section Type", ChunkSection.class); + } + + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + List palette = chunkSection.getPalette(); + palette.clear(); + + // Reaad bits per block + int bitsPerBlock = buffer.readUnsignedByte(); + long maxEntryValue = (1L << bitsPerBlock) - 1; + + if (bitsPerBlock == 0) { + bitsPerBlock = 14; + } + if (bitsPerBlock < 4) { + bitsPerBlock = 4; + } + if (bitsPerBlock > 8) { + bitsPerBlock = 14; + } + int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); + // Read palette + for (int i = 0; i < paletteLength; i++) { + palette.add(Type.VAR_INT.read(buffer)); + } + + // Read blocks + long[] blockData = new long[Type.VAR_INT.read(buffer)]; + if (blockData.length > 0) { + for (int i = 0; i < blockData.length; i++) { + blockData[i] = buffer.readLong(); + } + for (int i = 0; i < ChunkSection.SIZE; i++) { + int bitIndex = i * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + int val; + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } + + if (bitsPerBlock == 14) { + chunkSection.setFlatBlock(i, val); + } else { + chunkSection.setPaletteIndex(i, val); + } + } + } + + return chunkSection; + } + + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + List palette = chunkSection.getPalette(); + + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock += 1; + } + + if (bitsPerBlock > 8) { + bitsPerBlock = 14; + } + + long maxEntryValue = (1L << bitsPerBlock) - 1; + buffer.writeByte(bitsPerBlock); + + + // Write pallet (or not) + if (bitsPerBlock != 14) { + Type.VAR_INT.write(buffer, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(buffer, mappedId); + } + } + + int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(buffer, length); + long[] data = new long[length]; + for (int index = 0; index < ChunkSection.SIZE; index++) { + int value = bitsPerBlock == 14 ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + buffer.writeLong(l); + } + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java new file mode 100644 index 000000000..66de27a4a --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java @@ -0,0 +1,43 @@ +package us.myles.ViaVersion.api.type.types.version; + +import io.netty.buffer.ByteBuf; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.Type; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; +import java.util.List; + +public class ChunkSectionType1_8 extends Type { + + public ChunkSectionType1_8() { + super("Chunk Section Type", ChunkSection.class); + } + + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + List palette = chunkSection.getPalette(); + palette.clear(); + + byte[] blockData = new byte[ChunkSection.SIZE * 2]; + buffer.readBytes(blockData); + ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); + + for (int i = 0; i < ChunkSection.SIZE; i++) { + int mask = blockBuf.get(); + int type = mask >> 4; + int data = mask & 0xF; + chunkSection.setBlock(i, type, data); + } + + return chunkSection; + } + + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + throw new NotImplementedException(); + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java new file mode 100644 index 000000000..98d6b3b4d --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java @@ -0,0 +1,110 @@ +package us.myles.ViaVersion.api.type.types.version; + +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.Type; + +import java.util.List; + +public class ChunkSectionType1_9 extends Type { + + public ChunkSectionType1_9() { + super("Chunk Section Type", ChunkSection.class); + } + + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + List palette = chunkSection.getPalette(); + palette.clear(); + + // Reaad bits per block + int bitsPerBlock = buffer.readUnsignedByte(); + long maxEntryValue = (1L << bitsPerBlock) - 1; + + if (bitsPerBlock == 0) { + bitsPerBlock = 13; + } + if (bitsPerBlock < 4) { + bitsPerBlock = 4; + } + if (bitsPerBlock > 8) { + bitsPerBlock = 13; + } + int paletteLength = Type.VAR_INT.read(buffer); + // Read palette + for (int i = 0; i < paletteLength; i++) { + if (bitsPerBlock != 13) { + palette.add(Type.VAR_INT.read(buffer)); + } else { + Type.VAR_INT.read(buffer); + } + } + + // Read blocks + long[] blockData = new long[Type.VAR_INT.read(buffer)]; + if (blockData.length > 0) { + for (int i = 0; i < blockData.length; i++) { + blockData[i] = buffer.readLong(); + } + for (int i = 0; i < ChunkSection.SIZE; i++) { + int bitIndex = i * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + int val; + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } + + if (bitsPerBlock == 13) { + chunkSection.setBlock(i, val >> 4, val & 0xF); + } else { + chunkSection.setPaletteIndex(i, val); + } + } + } + + return chunkSection; + } + + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + List palette = chunkSection.getPalette(); + + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock += 1; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + buffer.writeByte(bitsPerBlock); + + // Write pallet + Type.VAR_INT.write(buffer, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(buffer, mappedId); + } + + int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(buffer, length); + long[] data = new long[length]; + for (int index = 0; index < ChunkSection.SIZE; index++) { + int value = chunkSection.getPaletteIndex(index); + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + buffer.writeLong(l); + } + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_13.java index 415a0e582..f8781f751 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_13.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion.api.type.types.version; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.type.Type; @@ -15,4 +16,6 @@ public class Types1_13 { * Metadata type for 1.13 */ public static final Type METADATA = new Metadata1_13Type(); + + public static final Type CHUNK_SECTION = new ChunkSectionType1_13(); } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java index 49ca88fae..f5a3747aa 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion.api.type.types.version; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.type.Type; @@ -15,4 +16,6 @@ public class Types1_8 { * Metadata type for 1.8 */ public static final Type METADATA = new Metadata1_8Type(); + + public static final Type CHUNK_SECTION = new ChunkSectionType1_8(); } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java index 2917c4d39..58468b42a 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion.api.type.types.version; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.type.Type; @@ -15,4 +16,6 @@ public class Types1_9 { * Metadata type for 1.9 */ public static final Type METADATA = new Metadata1_9Type(); + + public static final Type CHUNK_SECTION = new ChunkSectionType1_9(); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java deleted file mode 100644 index 92cd1b675..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java +++ /dev/null @@ -1,25 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AllArgsConstructor; -import lombok.Data; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; - -import java.util.List; - -@Data -@AllArgsConstructor -public class Chunk1_13 implements Chunk { - private int x; - private int z; - private boolean groundUp; - private int bitmask; - private ChunkSection1_13[] sections; - private byte[] biomeData; - private List blockEntities; - - @Override - public boolean isBiomeData() { - return biomeData != null; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java deleted file mode 100644 index 4361e0d70..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java +++ /dev/null @@ -1,311 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_13 implements ChunkSection { - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_13() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it fails to read - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Read bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - boolean directPalette = false; - - if (bitsPerBlock == 0) { - bitsPerBlock = 14; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock >= 9) { - directPalette = true; - bitsPerBlock = 14; - } - - int paletteLength = directPalette ? 0 : Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - palette.add(Type.VAR_INT.read(input)); - } - - // Read blocks - // Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex >> 6; // /64 - int endIndex = ((i + 1) * bitsPerBlock - 1) >> 6; // /64 - int startBitSubIndex = bitIndex & 0x3F; // % 64 - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (directPalette) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - @Override - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - @Override - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - @Override - public boolean hasSkyLight() { - return skyLight != null; - } - - @Override - public List getPalette() { - return palette; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index 95146d8ed..f6135bf05 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -254,7 +254,7 @@ public class WorldPackets { for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - int block = section.getBlock(x, y, z); + int block = section.getFlatBlock(x, y, z); if (storage.isWelcome(block)) { storage.store(new Position( (long) (x + (chunk.getX() << 4)), diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java index c6a63f690..5c6d1e65b 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java @@ -9,8 +9,7 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; -import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.Chunk1_13; -import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.ChunkSection1_13; +import us.myles.ViaVersion.api.type.types.version.Types1_13; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import java.util.ArrayList; @@ -33,7 +32,7 @@ public class Chunk1_13Type extends PartialType { Type.VAR_INT.read(input); BitSet usedSections = new BitSet(16); - ChunkSection1_13[] sections = new ChunkSection1_13[16]; + ChunkSection[] sections = new ChunkSection[16]; // Calculate section count from bitmask for (int i = 0; i < 16; i++) { if ((primaryBitmask & (1 << i)) != 0) { @@ -44,9 +43,8 @@ public class Chunk1_13Type extends PartialType { // Read sections for (int i = 0; i < 16; i++) { if (!usedSections.get(i)) continue; // Section not set - ChunkSection1_13 section = new ChunkSection1_13(); + ChunkSection section = Types1_13.CHUNK_SECTION.read(input); sections[i] = section; - section.readBlocks(input); section.readBlockLight(input); if (world.getEnvironment() == Environment.NORMAL) { section.readSkyLight(input); @@ -71,7 +69,7 @@ public class Chunk1_13Type extends PartialType { } } - return new Chunk1_13(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); } @Override @@ -86,7 +84,7 @@ public class Chunk1_13Type extends PartialType { for (int i = 0; i < 16; i++) { ChunkSection section = chunk.getSections()[i]; if (section == null) continue; // Section not set - section.writeBlocks1_13(buf); + Types1_13.CHUNK_SECTION.write(buf, section); section.writeBlockLight(buf); if (!section.hasSkyLight()) continue; // No sky light, we're done here. diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java deleted file mode 100644 index 6f899ff61..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java +++ /dev/null @@ -1,25 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AllArgsConstructor; -import lombok.Data; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; - -import java.util.List; - -@Data -@AllArgsConstructor -public class Chunk1_9_3_4 implements Chunk { - private int x; - private int z; - private boolean groundUp; - private int bitmask; - private ChunkSection1_9_3_4[] sections; - private byte[] biomeData; - private List blockEntities; - - @Override - public boolean isBiomeData() { - return biomeData != null; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java deleted file mode 100644 index d822c8475..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java +++ /dev/null @@ -1,368 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9_3_4 implements ChunkSection { - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9_3_4() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - /** - * Set a flat block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - */ - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it fails to read - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Read bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(input)); - } else { - Type.VAR_INT.read(input); - } - } - - // Read blocks - //Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (bitsPerBlock == 13) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } - - @Override - public List getPalette() { - return palette; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java index 58f563f05..87e0e86e0 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java @@ -9,8 +9,7 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; -import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4; -import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4; +import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import java.util.ArrayList; @@ -34,7 +33,7 @@ public class Chunk1_9_3_4Type extends PartialType { Type.VAR_INT.read(input); BitSet usedSections = new BitSet(16); - ChunkSection1_9_3_4[] sections = new ChunkSection1_9_3_4[16]; + ChunkSection[] sections = new ChunkSection[16]; // Calculate section count from bitmask for (int i = 0; i < 16; i++) { if ((primaryBitmask & (1 << i)) != 0) { @@ -45,9 +44,8 @@ public class Chunk1_9_3_4Type extends PartialType { // Read sections for (int i = 0; i < 16; i++) { if (!usedSections.get(i)) continue; // Section not set - ChunkSection1_9_3_4 section = new ChunkSection1_9_3_4(); + ChunkSection section = Types1_9.CHUNK_SECTION.read(input); sections[i] = section; - section.readBlocks(input); section.readBlockLight(input); if (world.getEnvironment() == Environment.NORMAL) { section.readSkyLight(input); @@ -69,7 +67,7 @@ public class Chunk1_9_3_4Type extends PartialType { } } - return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); } @Override @@ -84,7 +82,7 @@ public class Chunk1_9_3_4Type extends PartialType { for (int i = 0; i < 16; i++) { ChunkSection section = chunk.getSections()[i]; if (section == null) continue; // Section not set - section.writeBlocks(buf); + Types1_9.CHUNK_SECTION.write(buf, section); section.writeBlockLight(buf); if (!section.hasSkyLight()) continue; // No sky light, we're done here. diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java deleted file mode 100644 index 5da9fa4c9..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java +++ /dev/null @@ -1,24 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AllArgsConstructor; -import lombok.Data; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; - -import java.util.List; - -@Data -@AllArgsConstructor -public class Chunk1_9_1_2 implements Chunk { - private int x; - private int z; - private boolean groundUp; - private int bitmask; - private final ChunkSection1_9_1_2[] sections; - private byte[] biomeData; - private List blockEntities; - - public boolean isBiomeData() { - return biomeData != null; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java deleted file mode 100644 index c0c383b4f..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java +++ /dev/null @@ -1,360 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9_1_2 implements ChunkSection { - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9_1_2() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it failed to read properly - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Reaad bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(input)); - } else { - Type.VAR_INT.read(input); - } - } - - // Read blocks - // Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (bitsPerBlock == 13) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - @Override - public List getPalette() { - return palette; - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java index 621c303ac..77d483144 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java @@ -9,10 +9,9 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; +import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4; -import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.Chunk1_9_1_2; -import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.ChunkSection1_9_1_2; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import java.util.ArrayList; @@ -37,7 +36,7 @@ public class Chunk1_9_1_2Type extends PartialType { int size = Type.VAR_INT.read(input); BitSet usedSections = new BitSet(16); - ChunkSection1_9_1_2[] sections = new ChunkSection1_9_1_2[16]; + ChunkSection[] sections = new ChunkSection[16]; // Calculate section count from bitmask for (int i = 0; i < 16; i++) { if ((primaryBitmask & (1 << i)) != 0) { @@ -48,9 +47,8 @@ public class Chunk1_9_1_2Type extends PartialType { // Read sections for (int i = 0; i < 16; i++) { if (!usedSections.get(i)) continue; // Section not set - ChunkSection1_9_1_2 section = new ChunkSection1_9_1_2(); + ChunkSection section = Types1_9.CHUNK_SECTION.read(input); sections[i] = section; - section.readBlocks(input); section.readBlockLight(input); if (world.getEnvironment() == Environment.NORMAL) { section.readSkyLight(input); @@ -67,7 +65,7 @@ public class Chunk1_9_1_2Type extends PartialType { input.readBytes(biomeData); } - return new Chunk1_9_1_2(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, new ArrayList()); + return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, new ArrayList()); } @Override @@ -82,7 +80,7 @@ public class Chunk1_9_1_2Type extends PartialType { for (int i = 0; i < 16; i++) { ChunkSection section = chunk.getSections()[i]; if (section == null) continue; // Section not set - section.writeBlocks(buf); + Types1_9.CHUNK_SECTION.write(buf, section); section.writeBlockLight(buf); if (!section.hasSkyLight()) continue; // No sky light, we're done here. diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java index b80cecf30..dd775204d 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java @@ -2,26 +2,20 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.ToString; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import java.util.ArrayList; import java.util.List; -@RequiredArgsConstructor -@Getter -@ToString -public class Chunk1_9to1_8 implements Chunk { - private final int x; - private final int z; - private final boolean groundUp; - private final int primaryBitmask; - private final ChunkSection1_9to1_8[] sections; - private final byte[] biomeData; - private final List blockEntities; +public class Chunk1_9to1_8 extends Chunk { + @Getter private boolean unloadPacket = false; + public Chunk1_9to1_8(int x, int z, boolean groundUp, int bitmask, ChunkSection[] sections, byte[] biomeData, List blockEntities) { + super(x, z, groundUp, bitmask, sections, biomeData, blockEntities); + } + /** * Chunk unload. * @@ -29,8 +23,7 @@ public class Chunk1_9to1_8 implements Chunk { * @param z coord */ public Chunk1_9to1_8(int x, int z) { - this(x, z, true, 0, new ChunkSection1_9to1_8[16], null, - new ArrayList()); + this(x, z, true, 0, new ChunkSection[16], null, new ArrayList()); this.unloadPacket = true; } @@ -47,9 +40,4 @@ public class Chunk1_9to1_8 implements Chunk { public boolean isBiomeData() { return biomeData != null; } - - @Override - public int getBitmask() { - return primaryBitmask; - } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java deleted file mode 100644 index e77518363..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java +++ /dev/null @@ -1,263 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9to1_8 implements ChunkSection { - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9to1_8() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - @Override - public List getPalette() { - return palette; - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java index 8a60e7b57..f6605c692 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java @@ -24,7 +24,7 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.PlaceBlockTracker; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.Chunk1_9to1_8Type; import java.io.IOException; import java.util.List; @@ -121,7 +121,7 @@ public class WorldPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); - Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new ChunkType(clientChunks)); + Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new Chunk1_9to1_8Type(clientChunks)); if (chunk.isUnloadPacket()) { wrapper.setId(0x1D); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java similarity index 75% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java index eda3efd5b..40115b9a4 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java @@ -4,23 +4,22 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; +import us.myles.ViaVersion.api.type.types.version.Types1_8; +import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4; import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.ChunkSection1_9to1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.BitSet; import java.util.logging.Level; -public class ChunkType extends PartialType { +public class Chunk1_9to1_8Type extends PartialType { /** * Amount of sections in a chunks. */ @@ -34,7 +33,7 @@ public class ChunkType extends PartialType { */ private static final int BIOME_DATA_LENGTH = 256; - public ChunkType(ClientChunks chunks) { + public Chunk1_9to1_8Type(ClientChunks chunks) { super(chunks, Chunk.class); } @@ -61,7 +60,7 @@ public class ChunkType extends PartialType { // Data to be read BitSet usedSections = new BitSet(16); - ChunkSection1_9to1_8[] sections = new ChunkSection1_9to1_8[16]; + ChunkSection[] sections = new ChunkSection[16]; byte[] biomeData = null; // Calculate section count from bitmask @@ -87,41 +86,27 @@ public class ChunkType extends PartialType { // Read blocks for (int i = 0; i < SECTION_COUNT; i++) { if (!usedSections.get(i)) continue; // Section not set - ChunkSection1_9to1_8 section = new ChunkSection1_9to1_8(); + ChunkSection section = Types1_8.CHUNK_SECTION.read(input); sections[i] = section; - // Read block data and convert to short buffer - byte[] blockData = new byte[ChunkSection1_9to1_8.SIZE * 2]; - input.readBytes(blockData); - ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); - - for (int j = 0; j < ChunkSection1_9to1_8.SIZE; j++) { - int mask = blockBuf.get(); - int type = mask >> 4; - int data = mask & 0xF; - if (replacePistons && type == 36) - type = replacementId; - section.setBlock(j, type, data); + if (replacePistons && section.getPalette().contains(36)) { + section.getPalette().set(section.getPalette().indexOf(36), replacementId); } } // Read block light for (int i = 0; i < SECTION_COUNT; i++) { if (!usedSections.get(i)) continue; // Section not set, has no light - byte[] blockLightArray = new byte[ChunkSection1_9to1_8.LIGHT_LENGTH]; - input.readBytes(blockLightArray); - sections[i].setBlockLight(blockLightArray); + sections[i].readBlockLight(input); } // Read sky light int bytesLeft = dataLength - (input.readerIndex() - startIndex); - if (bytesLeft >= ChunkSection1_9to1_8.LIGHT_LENGTH) { + if (bytesLeft >= ChunkSection.LIGHT_LENGTH) { for (int i = 0; i < SECTION_COUNT; i++) { if (!usedSections.get(i)) continue; // Section not set, has no light - byte[] skyLightArray = new byte[ChunkSection1_9to1_8.LIGHT_LENGTH]; - input.readBytes(skyLightArray); - sections[i].setSkyLight(skyLightArray); - bytesLeft -= ChunkSection1_9to1_8.LIGHT_LENGTH; + sections[i].readSkyLight(input); + bytesLeft -= ChunkSection.LIGHT_LENGTH; } } @@ -151,13 +136,13 @@ public class ChunkType extends PartialType { output.writeInt(chunk.getZ()); if (chunk.isUnloadPacket()) return; output.writeByte(chunk.isGroundUp() ? 0x01 : 0x00); - Type.VAR_INT.write(output, chunk.getPrimaryBitmask()); + Type.VAR_INT.write(output, chunk.getBitmask()); ByteBuf buf = output.alloc().buffer(); for (int i = 0; i < SECTION_COUNT; i++) { - ChunkSection1_9to1_8 section = chunk.getSections()[i]; + ChunkSection section = chunk.getSections()[i]; if (section == null) continue; // Section not set - section.writeBlocks(buf); + Types1_9.CHUNK_SECTION.write(buf, section); section.writeBlockLight(buf); if (!section.hasSkyLight()) continue; // No sky light, we're done here. From 82013d5737d1c3a57524588ac06182d3fb8a8cc1 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Thu, 25 Oct 2018 20:26:24 +0200 Subject: [PATCH 16/24] Keep Chunk as an interface --- .../api/minecraft/chunks/BaseChunk.java | 24 +++++++++++++++ .../api/minecraft/chunks/Chunk.java | 30 +++++++++---------- .../minecraft/chunks/Chunk1_8.java} | 10 +++---- .../api/minecraft/chunks/ChunkSection.java | 3 -- .../types/Chunk1_13Type.java | 3 +- .../types/Chunk1_9_3_4Type.java | 3 +- .../types/Chunk1_9_1_2Type.java | 3 +- .../packets/WorldPackets.java | 4 +-- .../types/Chunk1_9to1_8Type.java | 10 +++---- 9 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/BaseChunk.java rename common/src/main/java/us/myles/ViaVersion/{protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java => api/minecraft/chunks/Chunk1_8.java} (65%) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/BaseChunk.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/BaseChunk.java new file mode 100644 index 000000000..82dd09429 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/BaseChunk.java @@ -0,0 +1,24 @@ +package us.myles.ViaVersion.api.minecraft.chunks; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@AllArgsConstructor +@Data +public class BaseChunk implements Chunk { + protected int x; + protected int z; + protected boolean groundUp; + protected int bitmask; + protected ChunkSection[] sections; + protected byte[] biomeData; + protected List blockEntities; + + @Override + public boolean isBiomeData() { + return biomeData != null; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java index 67e2c188b..f5b078748 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java @@ -1,23 +1,23 @@ package us.myles.ViaVersion.api.minecraft.chunks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AllArgsConstructor; -import lombok.Data; import java.util.List; -@Data -@AllArgsConstructor -public class Chunk { - protected int x; - protected int z; - protected boolean groundUp; - protected int bitmask; - protected ChunkSection[] sections; - protected byte[] biomeData; - protected List blockEntities; +public interface Chunk { + int getX(); - public boolean isBiomeData() { - return biomeData != null; - } + int getZ(); + + boolean isBiomeData(); + + int getBitmask(); + + ChunkSection[] getSections(); + + byte[] getBiomeData(); + + List getBlockEntities(); + + boolean isGroundUp(); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk1_8.java similarity index 65% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk1_8.java index dd775204d..4bfe7f3ed 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk1_8.java @@ -1,18 +1,16 @@ -package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks; +package us.myles.ViaVersion.api.minecraft.chunks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.Getter; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import java.util.ArrayList; import java.util.List; -public class Chunk1_9to1_8 extends Chunk { +public class Chunk1_8 extends BaseChunk { @Getter private boolean unloadPacket = false; - public Chunk1_9to1_8(int x, int z, boolean groundUp, int bitmask, ChunkSection[] sections, byte[] biomeData, List blockEntities) { + public Chunk1_8(int x, int z, boolean groundUp, int bitmask, ChunkSection[] sections, byte[] biomeData, List blockEntities) { super(x, z, groundUp, bitmask, sections, biomeData, blockEntities); } @@ -22,7 +20,7 @@ public class Chunk1_9to1_8 extends Chunk { * @param x coord * @param z coord */ - public Chunk1_9to1_8(int x, int z) { + public Chunk1_8(int x, int z) { this(x, z, true, 0, new ChunkSection[16], null, new ArrayList()); this.unloadPacket = true; } diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 2afdbc2cb..133c3f831 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -14,9 +14,6 @@ public class ChunkSection { * Length of the sky and block light nibble arrays. */ public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ private final List palette = Lists.newArrayList(); private final int[] blocks; private NibbleArray blockLight; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java index 5c6d1e65b..3d4e40154 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java @@ -4,6 +4,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.Environment; +import us.myles.ViaVersion.api.minecraft.chunks.BaseChunk; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; @@ -69,7 +70,7 @@ public class Chunk1_13Type extends PartialType { } } - return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + return new BaseChunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java index 87e0e86e0..5f7188ca4 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java @@ -4,6 +4,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.Environment; +import us.myles.ViaVersion.api.minecraft.chunks.BaseChunk; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; @@ -67,7 +68,7 @@ public class Chunk1_9_3_4Type extends PartialType { } } - return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + return new BaseChunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java index 77d483144..63ff5695d 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java @@ -4,6 +4,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.Environment; +import us.myles.ViaVersion.api.minecraft.chunks.BaseChunk; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.PartialType; @@ -65,7 +66,7 @@ public class Chunk1_9_1_2Type extends PartialType { input.readBytes(biomeData); } - return new Chunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, new ArrayList()); + return new BaseChunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, new ArrayList()); } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java index f6605c692..f6fb17809 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java @@ -16,7 +16,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.CommandBlockProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect; @@ -121,7 +121,7 @@ public class WorldPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); - Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new Chunk1_9to1_8Type(clientChunks)); + Chunk1_8 chunk = (Chunk1_8) wrapper.passthrough(new Chunk1_9to1_8Type(clientChunks)); if (chunk.isUnloadPacket()) { wrapper.setId(0x1D); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java index 40115b9a4..877a5aa5c 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java @@ -12,7 +12,7 @@ import us.myles.ViaVersion.api.type.types.version.Types1_8; import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; import java.util.ArrayList; @@ -77,7 +77,7 @@ public class Chunk1_9to1_8Type extends PartialType { if (sectionCount == 0 && groundUp && !isBulkPacket && param.getLoadedChunks().contains(chunkHash)) { // This is a chunks unload packet param.getLoadedChunks().remove(chunkHash); - return new Chunk1_9to1_8(chunkX, chunkZ); + return new Chunk1_8(chunkX, chunkZ); } int startIndex = input.readerIndex(); @@ -123,14 +123,14 @@ public class Chunk1_9to1_8Type extends PartialType { } // Return chunks - return new Chunk1_9to1_8(chunkX, chunkZ, groundUp, bitmask, sections, biomeData, new ArrayList()); + return new Chunk1_8(chunkX, chunkZ, groundUp, bitmask, sections, biomeData, new ArrayList()); } @Override public void write(ByteBuf output, ClientChunks param, Chunk input) throws Exception { - if (!(input instanceof Chunk1_9to1_8)) throw new Exception("Incompatible chunk, " + input.getClass()); + if (!(input instanceof Chunk1_8)) throw new Exception("Incompatible chunk, " + input.getClass()); - Chunk1_9to1_8 chunk = (Chunk1_9to1_8) input; + Chunk1_8 chunk = (Chunk1_8) input; // Write primary info output.writeInt(chunk.getX()); output.writeInt(chunk.getZ()); From ce65c7f583b61c9685a0343e28b9739dd0df30e8 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Fri, 26 Oct 2018 17:09:26 +0200 Subject: [PATCH 17/24] fix merge issues --- .../api/minecraft/chunks/ChunkSection.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 133c3f831..b3341b92e 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.minecraft.chunks; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; +import lombok.Getter; +import lombok.Setter; import java.util.List; @@ -14,10 +16,14 @@ public class ChunkSection { * Length of the sky and block light nibble arrays. */ public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - private final List palette = Lists.newArrayList(); + @Getter + private final List palette = Lists.newArrayList(); private final int[] blocks; private NibbleArray blockLight; private NibbleArray skyLight; + @Getter + @Setter + private int nonAirBlocksCount; public ChunkSection() { this.blocks = new int[SIZE]; @@ -160,10 +166,6 @@ public class ChunkSection { output.writeBytes(skyLight.getHandle()); } - public List getPalette() { - return palette; - } - /** * Check if sky light is present * From 9a87adf51b9d0064d2f182fa25cb9fd2797c2efb Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Mon, 12 Nov 2018 14:36:01 +0100 Subject: [PATCH 18/24] Use BiHashMap as palette --- .../api/minecraft/chunks/ChunkSection.java | 32 +-- .../types/version/ChunkSectionType1_13.java | 183 +++++++++--------- .../types/version/ChunkSectionType1_8.java | 47 +++-- .../types/version/ChunkSectionType1_9.java | 181 +++++++++-------- .../packets/WorldPackets.java | 13 +- .../packets/WorldPackets.java | 8 +- .../types/Chunk1_9_1_2Type.java | 6 +- .../types/Chunk1_9to1_8Type.java | 4 +- 8 files changed, 233 insertions(+), 241 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index b3341b92e..c08a89eb5 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -1,12 +1,11 @@ package us.myles.ViaVersion.api.minecraft.chunks; -import com.google.common.collect.Lists; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.Setter; -import java.util.List; - public class ChunkSection { /** * Size (dimensions) of blocks in a chunks section. @@ -17,7 +16,7 @@ public class ChunkSection { */ public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) @Getter - private final List palette = Lists.newArrayList(); + private BiMap palette = HashBiMap.create(); private final int[] blocks; private NibbleArray blockLight; private NibbleArray skyLight; @@ -28,11 +27,12 @@ public class ChunkSection { public ChunkSection() { this.blocks = new int[SIZE]; this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR + palette.put(0, 0); } /** * Set a block in the chunks + * This method will not update non-air blocks count * * @param x Block X * @param y Block Y @@ -58,12 +58,12 @@ public class ChunkSection { public int getFlatBlock(int x, int y, int z) { int index = blocks[index(x, y, z)]; - return palette.get(index); + return palette.inverse().get(index); } public int getFlatBlock(int idx) { int index = blocks[idx]; - return palette.get(index); + return palette.inverse().get(index); } public void setBlock(int idx, int type, int data) { @@ -71,24 +71,24 @@ public class ChunkSection { } public void setPaletteIndex(int idx, int index) { - blocks[idx] = index; + blocks[idx] = index; } public int getPaletteIndex(int idx) { - return blocks[idx]; + return blocks[idx]; } /** - * Set a block in the chunks based on the index + * Set a block state in the chunk + * This method will not update non-air blocks count * - * @param idx Index - * @param id The raw or flat id of the block + * @param idx Index + * @param id The raw or flat id of the block */ public void setFlatBlock(int idx, int id) { - int index = palette.indexOf(id); - if (index == -1) { - index = palette.size(); - palette.add(id); + Integer index = palette.get(id); + if (index == null) { + palette.put(id, index = palette.size()); } blocks[idx] = index; diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java index ee6b89721..b2d7cf080 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java @@ -1,114 +1,113 @@ package us.myles.ViaVersion.api.type.types.version; +import com.google.common.collect.BiMap; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; -import java.util.List; - public class ChunkSectionType1_13 extends Type { - public ChunkSectionType1_13() { - super("Chunk Section Type", ChunkSection.class); - } + public ChunkSectionType1_13() { + super("Chunk Section Type", ChunkSection.class); + } - @Override - public ChunkSection read(ByteBuf buffer) throws Exception { - ChunkSection chunkSection = new ChunkSection(); - List palette = chunkSection.getPalette(); - palette.clear(); + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + BiMap palette = chunkSection.getPalette(); + palette.clear(); - // Reaad bits per block - int bitsPerBlock = buffer.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; + // Reaad bits per block + int bitsPerBlock = buffer.readUnsignedByte(); + long maxEntryValue = (1L << bitsPerBlock) - 1; - if (bitsPerBlock == 0) { - bitsPerBlock = 14; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 14; - } - int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); - // Read palette - for (int i = 0; i < paletteLength; i++) { - palette.add(Type.VAR_INT.read(buffer)); - } + if (bitsPerBlock == 0) { + bitsPerBlock = 14; + } + if (bitsPerBlock < 4) { + bitsPerBlock = 4; + } + if (bitsPerBlock > 8) { + bitsPerBlock = 14; + } + int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); + // Read palette + for (int i = 0; i < paletteLength; i++) { + palette.put(Type.VAR_INT.read(buffer), palette.size()); + } - // Read blocks - long[] blockData = new long[Type.VAR_INT.read(buffer)]; - if (blockData.length > 0) { - for (int i = 0; i < blockData.length; i++) { - blockData[i] = buffer.readLong(); - } - for (int i = 0; i < ChunkSection.SIZE; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } + // Read blocks + long[] blockData = new long[Type.VAR_INT.read(buffer)]; + if (blockData.length > 0) { + for (int i = 0; i < blockData.length; i++) { + blockData[i] = buffer.readLong(); + } + for (int i = 0; i < ChunkSection.SIZE; i++) { + int bitIndex = i * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + int val; + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } - if (bitsPerBlock == 14) { - chunkSection.setFlatBlock(i, val); - } else { - chunkSection.setPaletteIndex(i, val); - } - } - } + if (bitsPerBlock == 14) { + chunkSection.setFlatBlock(i, val); + } else { + chunkSection.setPaletteIndex(i, val); + } + } + } - return chunkSection; - } + return chunkSection; + } - @Override - public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - List palette = chunkSection.getPalette(); + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + BiMap palette = chunkSection.getPalette(); - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock += 1; + } - if (bitsPerBlock > 8) { - bitsPerBlock = 14; - } + if (bitsPerBlock > 8) { + bitsPerBlock = 14; + } - long maxEntryValue = (1L << bitsPerBlock) - 1; - buffer.writeByte(bitsPerBlock); + long maxEntryValue = (1L << bitsPerBlock) - 1; + buffer.writeByte(bitsPerBlock); - // Write pallet (or not) - if (bitsPerBlock != 14) { - Type.VAR_INT.write(buffer, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(buffer, mappedId); - } - } + // Write pallet (or not) + if (bitsPerBlock != 14) { + Type.VAR_INT.write(buffer, palette.size()); + for (int i = 0; i < palette.size(); i++) { + Type.VAR_INT.write(buffer, palette.inverse().get(i)); + } + } - int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(buffer, length); - long[] data = new long[length]; - for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = bitsPerBlock == 14 ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - buffer.writeLong(l); - } - } + int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(buffer, length); + long[] data = new long[length]; + for (int index = 0; index < ChunkSection.SIZE; index++) { + int value = bitsPerBlock == 14 ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + buffer.writeLong(l); + } + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java index 66de27a4a..e132d7f35 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java @@ -1,43 +1,40 @@ package us.myles.ViaVersion.api.type.types.version; import io.netty.buffer.ByteBuf; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; -import java.util.List; public class ChunkSectionType1_8 extends Type { - public ChunkSectionType1_8() { - super("Chunk Section Type", ChunkSection.class); - } + public ChunkSectionType1_8() { + super("Chunk Section Type", ChunkSection.class); + } - @Override - public ChunkSection read(ByteBuf buffer) throws Exception { - ChunkSection chunkSection = new ChunkSection(); - List palette = chunkSection.getPalette(); - palette.clear(); + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + chunkSection.getPalette().clear(); - byte[] blockData = new byte[ChunkSection.SIZE * 2]; - buffer.readBytes(blockData); - ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); + byte[] blockData = new byte[ChunkSection.SIZE * 2]; + buffer.readBytes(blockData); + ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); - for (int i = 0; i < ChunkSection.SIZE; i++) { - int mask = blockBuf.get(); - int type = mask >> 4; - int data = mask & 0xF; - chunkSection.setBlock(i, type, data); - } + for (int i = 0; i < ChunkSection.SIZE; i++) { + int mask = blockBuf.get(); + int type = mask >> 4; + int data = mask & 0xF; + chunkSection.setBlock(i, type, data); + } - return chunkSection; - } + return chunkSection; + } - @Override - public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - throw new NotImplementedException(); - } + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + throw new UnsupportedOperationException(); + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java index 98d6b3b4d..37758816c 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java @@ -1,110 +1,109 @@ package us.myles.ViaVersion.api.type.types.version; +import com.google.common.collect.BiMap; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; -import java.util.List; - public class ChunkSectionType1_9 extends Type { - public ChunkSectionType1_9() { - super("Chunk Section Type", ChunkSection.class); - } + public ChunkSectionType1_9() { + super("Chunk Section Type", ChunkSection.class); + } - @Override - public ChunkSection read(ByteBuf buffer) throws Exception { - ChunkSection chunkSection = new ChunkSection(); - List palette = chunkSection.getPalette(); - palette.clear(); + @Override + public ChunkSection read(ByteBuf buffer) throws Exception { + ChunkSection chunkSection = new ChunkSection(); + BiMap palette = chunkSection.getPalette(); + palette.clear(); - // Reaad bits per block - int bitsPerBlock = buffer.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; + // Reaad bits per block + int bitsPerBlock = buffer.readUnsignedByte(); + long maxEntryValue = (1L << bitsPerBlock) - 1; - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(buffer); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(buffer)); - } else { - Type.VAR_INT.read(buffer); - } - } + if (bitsPerBlock == 0) { + bitsPerBlock = 13; + } + if (bitsPerBlock < 4) { + bitsPerBlock = 4; + } + if (bitsPerBlock > 8) { + bitsPerBlock = 13; + } + int paletteLength = Type.VAR_INT.read(buffer); + // Read palette + for (int i = 0; i < paletteLength; i++) { + if (bitsPerBlock != 13) { + palette.put(Type.VAR_INT.read(buffer), palette.size()); + } else { + Type.VAR_INT.read(buffer); + } + } - // Read blocks - long[] blockData = new long[Type.VAR_INT.read(buffer)]; - if (blockData.length > 0) { - for (int i = 0; i < blockData.length; i++) { - blockData[i] = buffer.readLong(); - } - for (int i = 0; i < ChunkSection.SIZE; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } + // Read blocks + long[] blockData = new long[Type.VAR_INT.read(buffer)]; + if (blockData.length > 0) { + for (int i = 0; i < blockData.length; i++) { + blockData[i] = buffer.readLong(); + } + for (int i = 0; i < ChunkSection.SIZE; i++) { + int bitIndex = i * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + int val; + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } - if (bitsPerBlock == 13) { - chunkSection.setBlock(i, val >> 4, val & 0xF); - } else { - chunkSection.setPaletteIndex(i, val); - } - } - } + if (bitsPerBlock == 13) { + chunkSection.setBlock(i, val >> 4, val & 0xF); + } else { + chunkSection.setPaletteIndex(i, val); + } + } + } - return chunkSection; - } + return chunkSection; + } - @Override - public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - List palette = chunkSection.getPalette(); + @Override + public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { + BiMap palette = chunkSection.getPalette(); - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - buffer.writeByte(bitsPerBlock); + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock += 1; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + buffer.writeByte(bitsPerBlock); - // Write pallet - Type.VAR_INT.write(buffer, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(buffer, mappedId); - } + // Write pallet + Type.VAR_INT.write(buffer, palette.size()); + for (int i = 0; i < palette.size(); i++) { + Type.VAR_INT.write(buffer, palette.inverse().get(i)); + } - int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(buffer, length); - long[] data = new long[length]; - for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = chunkSection.getPaletteIndex(index); - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - buffer.writeLong(l); - } - } + int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(buffer, length); + long[] data = new long[length]; + for (int index = 0; index < ChunkSection.SIZE; index++) { + int value = chunkSection.getPaletteIndex(index); + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + buffer.writeLong(l); + } + } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java index 4e91dfee5..edae54c15 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion.protocols.protocol1_13_1to1_13.packets; +import com.google.common.collect.BiMap; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; @@ -27,16 +28,12 @@ public class WorldPackets { Chunk chunk = wrapper.passthrough(new Chunk1_13Type(clientWorld)); for (ChunkSection section : chunk.getSections()) { - if (section != null) { - for (int i = 0; i < section.getPalette().size(); i++) { - section.getPalette().set( - i, - Protocol1_13_1To1_13.getNewBlockStateId(section.getPalette().get(i)) - ); - } + if (section == null) continue; + BiMap inverse = section.getPalette().inverse(); + for (int i = 0; i < inverse.size(); i++) { + inverse.put(i, Protocol1_13_1To1_13.getNewBlockStateId(inverse.get(i))); } } - } }); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index f6135bf05..9dd01c2de 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -2,6 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.google.common.base.Optional; +import com.google.common.collect.BiMap; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; @@ -241,13 +242,14 @@ public class WorldPackets { boolean willStoreAnyBlock = false; - for (int p = 0; p < section.getPalette().size(); p++) { - int old = section.getPalette().get(p); + BiMap inverse = section.getPalette().inverse(); + for (int p = 0; p < inverse.size(); p++) { + int old = inverse.get(p); int newId = toNewId(old); if (storage.isWelcome(newId)) { willStoreAnyBlock = true; } - section.getPalette().set(p, newId); + inverse.put(p, newId); } if (willStoreAnyBlock) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java index 63ff5695d..6f3d1f6ee 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java @@ -54,10 +54,8 @@ public class Chunk1_9_1_2Type extends PartialType { if (world.getEnvironment() == Environment.NORMAL) { section.readSkyLight(input); } - if (replacePistons) { - if (section.getPalette().contains(36)) { - section.getPalette().set(section.getPalette().indexOf(36), replacementId); - } + if (replacePistons && section.getPalette().containsKey(36)) { + section.getPalette().put(replacementId, section.getPalette().remove(36)); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java index 877a5aa5c..eae734f1b 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java @@ -89,8 +89,8 @@ public class Chunk1_9to1_8Type extends PartialType { ChunkSection section = Types1_8.CHUNK_SECTION.read(input); sections[i] = section; - if (replacePistons && section.getPalette().contains(36)) { - section.getPalette().set(section.getPalette().indexOf(36), replacementId); + if (replacePistons && section.getPalette().containsKey(36)) { + section.getPalette().put(replacementId, section.getPalette().remove(36)); } } From 3b14dd3b04c55ceebc974af6c006254d9798b5d3 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Mon, 12 Nov 2018 16:08:01 +0100 Subject: [PATCH 19/24] Use methods for palette rewriting, fix "value already present" --- .../api/minecraft/chunks/ChunkSection.java | 18 ++++++++++++++++++ .../packets/WorldPackets.java | 6 ++---- .../packets/WorldPackets.java | 7 +++---- .../types/Chunk1_9_1_2Type.java | 4 ++-- .../types/Chunk1_9to1_8Type.java | 4 ++-- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index c08a89eb5..88b69da0e 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -78,6 +78,24 @@ public class ChunkSection { return blocks[idx]; } + public int getPaletteSize() { + return palette.size(); + } + + public int getPaletteEntry(int index) { + if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException(); + return palette.inverse().get(index); + } + + public void setPaletteEntry(int index, int id) { + if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException(); + palette.forcePut(id, index); + } + + public void replacePaletteEntry(int oldId, int newId) { + if (palette.containsKey(oldId)) palette.put(newId, palette.remove(oldId)); + } + /** * Set a block state in the chunk * This method will not update non-air blocks count diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java index edae54c15..f643d423f 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13_1to1_13/packets/WorldPackets.java @@ -1,6 +1,5 @@ package us.myles.ViaVersion.protocols.protocol1_13_1to1_13.packets; -import com.google.common.collect.BiMap; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; @@ -29,9 +28,8 @@ public class WorldPackets { for (ChunkSection section : chunk.getSections()) { if (section == null) continue; - BiMap inverse = section.getPalette().inverse(); - for (int i = 0; i < inverse.size(); i++) { - inverse.put(i, Protocol1_13_1To1_13.getNewBlockStateId(inverse.get(i))); + for (int i = 0; i < section.getPaletteSize(); i++) { + section.setPaletteEntry(i, Protocol1_13_1To1_13.getNewBlockStateId(section.getPaletteEntry(i))); } } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index 9dd01c2de..813732bc6 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -242,14 +242,13 @@ public class WorldPackets { boolean willStoreAnyBlock = false; - BiMap inverse = section.getPalette().inverse(); - for (int p = 0; p < inverse.size(); p++) { - int old = inverse.get(p); + for (int p = 0; p < section.getPaletteSize(); p++) { + int old = section.getPaletteEntry(p); int newId = toNewId(old); if (storage.isWelcome(newId)) { willStoreAnyBlock = true; } - inverse.put(p, newId); + section.setPaletteEntry(p, newId); } if (willStoreAnyBlock) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java index 6f3d1f6ee..64a0bc949 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java @@ -54,8 +54,8 @@ public class Chunk1_9_1_2Type extends PartialType { if (world.getEnvironment() == Environment.NORMAL) { section.readSkyLight(input); } - if (replacePistons && section.getPalette().containsKey(36)) { - section.getPalette().put(replacementId, section.getPalette().remove(36)); + if (replacePistons) { + section.replacePaletteEntry(36, replacementId); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java index eae734f1b..4f2d47b18 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/Chunk1_9to1_8Type.java @@ -89,8 +89,8 @@ public class Chunk1_9to1_8Type extends PartialType { ChunkSection section = Types1_8.CHUNK_SECTION.read(input); sections[i] = section; - if (replacePistons && section.getPalette().containsKey(36)) { - section.getPalette().put(replacementId, section.getPalette().remove(36)); + if (replacePistons) { + section.replacePaletteEntry(36, replacementId); } } From cf0bd6f021bd09396b5212b5d7c708f3602f19b2 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Mon, 12 Nov 2018 17:10:19 +0100 Subject: [PATCH 20/24] Use List and Map, fixes duplicate block ids in palette causing issues --- .../api/minecraft/chunks/ChunkSection.java | 52 +++++++++++++------ .../types/version/ChunkSectionType1_13.java | 16 +++--- .../types/version/ChunkSectionType1_8.java | 2 +- .../types/version/ChunkSectionType1_9.java | 15 +++--- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 88b69da0e..9305a5994 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -1,11 +1,14 @@ package us.myles.ViaVersion.api.minecraft.chunks; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class ChunkSection { /** * Size (dimensions) of blocks in a chunks section. @@ -15,8 +18,8 @@ public class ChunkSection { * Length of the sky and block light nibble arrays. */ public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - @Getter - private BiMap palette = HashBiMap.create(); + private List palette = new ArrayList<>(); + private Map inversePalette = new HashMap<>(); private final int[] blocks; private NibbleArray blockLight; private NibbleArray skyLight; @@ -27,7 +30,8 @@ public class ChunkSection { public ChunkSection() { this.blocks = new int[SIZE]; this.blockLight = new NibbleArray(SIZE); - palette.put(0, 0); + palette.add(0); + inversePalette.put(0, 0); } /** @@ -58,12 +62,12 @@ public class ChunkSection { public int getFlatBlock(int x, int y, int z) { int index = blocks[index(x, y, z)]; - return palette.inverse().get(index); + return palette.get(index); } public int getFlatBlock(int idx) { int index = blocks[idx]; - return palette.inverse().get(index); + return palette.get(index); } public void setBlock(int idx, int type, int data) { @@ -84,16 +88,32 @@ public class ChunkSection { public int getPaletteEntry(int index) { if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException(); - return palette.inverse().get(index); + return palette.get(index); } public void setPaletteEntry(int index, int id) { if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException(); - palette.forcePut(id, index); + palette.set(index, id); + inversePalette.put(id, index); } public void replacePaletteEntry(int oldId, int newId) { - if (palette.containsKey(oldId)) palette.put(newId, palette.remove(oldId)); + Integer index = inversePalette.remove(oldId); + if (index == null) return; + inversePalette.put(newId, index); + for (int i = 0; i < palette.size(); i++) { + if (palette.get(i) == oldId) palette.set(i, newId); + } + } + + public void addPaletteEntry(int id) { + inversePalette.put(id, palette.size()); + palette.add(id); + } + + public void clearPalette() { + palette.clear(); + inversePalette.clear(); } /** @@ -104,12 +124,14 @@ public class ChunkSection { * @param id The raw or flat id of the block */ public void setFlatBlock(int idx, int id) { - Integer index = palette.get(id); - if (index == null) { - palette.put(id, index = palette.size()); - } + Integer index = inversePalette.get(id); + if (index == null) { + index = palette.size(); + palette.add(id); + inversePalette.put(id, index); + } - blocks[idx] = index; + blocks[idx] = index; } /** diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java index b2d7cf080..e6e265475 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java @@ -1,6 +1,5 @@ package us.myles.ViaVersion.api.type.types.version; -import com.google.common.collect.BiMap; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; @@ -14,8 +13,6 @@ public class ChunkSectionType1_13 extends Type { @Override public ChunkSection read(ByteBuf buffer) throws Exception { ChunkSection chunkSection = new ChunkSection(); - BiMap palette = chunkSection.getPalette(); - palette.clear(); // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); @@ -32,8 +29,9 @@ public class ChunkSectionType1_13 extends Type { } int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); // Read palette + chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { - palette.put(Type.VAR_INT.read(buffer), palette.size()); + chunkSection.addPaletteEntry(Type.VAR_INT.read(buffer)); } // Read blocks @@ -68,10 +66,8 @@ public class ChunkSectionType1_13 extends Type { @Override public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - BiMap palette = chunkSection.getPalette(); - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { + while (chunkSection.getPaletteSize() > 1 << bitsPerBlock) { bitsPerBlock += 1; } @@ -85,9 +81,9 @@ public class ChunkSectionType1_13 extends Type { // Write pallet (or not) if (bitsPerBlock != 14) { - Type.VAR_INT.write(buffer, palette.size()); - for (int i = 0; i < palette.size(); i++) { - Type.VAR_INT.write(buffer, palette.inverse().get(i)); + Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); + for (int i = 0; i < chunkSection.getPaletteSize(); i++) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java index e132d7f35..2cc3f478b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java @@ -17,7 +17,7 @@ public class ChunkSectionType1_8 extends Type { @Override public ChunkSection read(ByteBuf buffer) throws Exception { ChunkSection chunkSection = new ChunkSection(); - chunkSection.getPalette().clear(); + chunkSection.clearPalette(); byte[] blockData = new byte[ChunkSection.SIZE * 2]; buffer.readBytes(blockData); diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java index 37758816c..8a596e24a 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java @@ -14,8 +14,6 @@ public class ChunkSectionType1_9 extends Type { @Override public ChunkSection read(ByteBuf buffer) throws Exception { ChunkSection chunkSection = new ChunkSection(); - BiMap palette = chunkSection.getPalette(); - palette.clear(); // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); @@ -32,9 +30,10 @@ public class ChunkSectionType1_9 extends Type { } int paletteLength = Type.VAR_INT.read(buffer); // Read palette + chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { if (bitsPerBlock != 13) { - palette.put(Type.VAR_INT.read(buffer), palette.size()); + chunkSection.addPaletteEntry(Type.VAR_INT.read(buffer)); } else { Type.VAR_INT.read(buffer); } @@ -72,19 +71,17 @@ public class ChunkSectionType1_9 extends Type { @Override public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - BiMap palette = chunkSection.getPalette(); - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { + while (chunkSection.getPaletteSize() > 1 << bitsPerBlock) { bitsPerBlock += 1; } long maxEntryValue = (1L << bitsPerBlock) - 1; buffer.writeByte(bitsPerBlock); // Write pallet - Type.VAR_INT.write(buffer, palette.size()); - for (int i = 0; i < palette.size(); i++) { - Type.VAR_INT.write(buffer, palette.inverse().get(i)); + Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); + for (int i = 0; i < chunkSection.getPaletteSize(); i++) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); } int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); From 34c701e0399b3cea6b9940f39b14ba8025fa5a08 Mon Sep 17 00:00:00 2001 From: Marco Neuhaus Date: Tue, 6 Nov 2018 21:42:15 +0100 Subject: [PATCH 21/24] fix chunk unload packet --- .../protocol1_9to1_8/packets/WorldPackets.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java index f6fb17809..0b0540559 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java @@ -121,16 +121,20 @@ public class WorldPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); - Chunk1_8 chunk = (Chunk1_8) wrapper.passthrough(new Chunk1_9to1_8Type(clientChunks)); + Chunk1_9to1_8Type type = new Chunk1_9to1_8Type(clientChunks); + Chunk1_8 chunk = (Chunk1_8) wrapper.read(type); if (chunk.isUnloadPacket()) { wrapper.setId(0x1D); + wrapper.write(Type.INT, chunk.getX()); + wrapper.write(Type.INT, chunk.getZ()); // Remove commandBlocks on chunk unload CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class); provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ()); + } else { + wrapper.write(type, chunk); + // eat any other data (Usually happens with unload packets) } - - // eat any other data (Usually happens with unload packets) wrapper.read(Type.REMAINING_BYTES); } }); From d0300de136e747520dccf6f3485448b34bdd21cf Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:08:51 +0000 Subject: [PATCH 22/24] Prevent initialization error --- .../main/java/us/myles/ViaVersion/VelocityPlugin.java | 3 ++- .../ViaVersion/velocity/platform/VelocityViaConfig.java | 9 +++++++-- .../velocity/platform/VelocityViaInjector.java | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java index f16cad720..94b131740 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -56,7 +56,7 @@ public class VelocityPlugin implements ViaPlatform { @Inject @DataDirectory private Path configDir; - private VelocityViaAPI api = new VelocityViaAPI(); + private VelocityViaAPI api; private VelocityViaConfig conf; @Subscribe @@ -64,6 +64,7 @@ public class VelocityPlugin implements ViaPlatform { PROXY = proxy; VelocityCommandHandler commandHandler = new VelocityCommandHandler(); PROXY.getCommandManager().register(commandHandler, "viaver", "vvvelocity", "viaversion"); + api = new VelocityViaAPI(); conf = new VelocityViaConfig(configDir.toFile()); logger = new LoggerWrapper(loggerslf4j); Via.init(ViaManager.builder() diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java index 373bd5c61..9d8da33f0 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java @@ -1,7 +1,6 @@ package us.myles.ViaVersion.velocity.platform; import us.myles.ViaVersion.api.ViaVersionConfig; -import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.util.Config; @@ -49,7 +48,13 @@ public class VelocityViaConfig extends Config implements ViaVersionConfig { } // Ensure default exists if (!servers.containsKey("default")) { - servers.put("default", ProtocolRegistry.SERVER_PROTOCOL); + // Side note: This doesn't use ProtocolRegistry as it doesn't know the protocol version at boot. + try { + servers.put("default", VelocityViaInjector.getLowestSupportedProtocolVersion()); + } catch (Exception e) { + // Something went very wrong + e.printStackTrace(); + } } // Put back config.put("velocity-servers", servers); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java index 78e5a532b..4673d23c4 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java @@ -26,6 +26,10 @@ public class VelocityViaInjector implements ViaInjector { @Override public int getServerProtocolVersion() throws Exception { + return getLowestSupportedProtocolVersion(); + } + + public static int getLowestSupportedProtocolVersion() throws Exception { return ReflectionUtil.getStatic(Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), "MINIMUM_GENERIC_VERSION", int.class); } From 8549c2256789af44ae2cfd7edc28d6b1b26da21a Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:12:19 +0000 Subject: [PATCH 23/24] Change the name of the config class to be more consistent --- .../main/java/us/myles/ViaVersion/ViaVersionPlugin.java | 4 ++-- .../{BukkitConfigAPI.java => BukkitViaConfig.java} | 6 +++--- .../src/main/java/us/myles/ViaVersion/BungeePlugin.java | 6 +++--- .../ViaVersion/bungee/commands/subs/ProbeSubCmd.java | 4 ++-- .../{BungeeConfigAPI.java => BungeeViaConfig.java} | 6 +++--- .../bungee/service/ProtocolDetectorService.java | 8 ++++---- .../src/main/java/us/myles/ViaVersion/SpongePlugin.java | 7 ++----- .../{SpongeConfigAPI.java => SpongeViaConfig.java} | 4 ++-- 8 files changed, 21 insertions(+), 24 deletions(-) rename bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/{BukkitConfigAPI.java => BukkitViaConfig.java} (97%) rename bungee/src/main/java/us/myles/ViaVersion/bungee/platform/{BungeeConfigAPI.java => BungeeViaConfig.java} (97%) rename sponge/src/main/java/us/myles/ViaVersion/sponge/platform/{SpongeConfigAPI.java => SpongeViaConfig.java} (97%) diff --git a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index d4c326384..f597c65c1 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -34,7 +34,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform { private boolean lateBind = false; private boolean protocolSupport = false; @Getter - private BukkitConfigAPI conf; + private BukkitViaConfig conf; @Getter private ViaAPI api = new BukkitViaAPI(this); private List queuedTasks = new ArrayList<>(); @@ -51,7 +51,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform { .loader(new BukkitViaLoader(this)) .build()); // Config magic - conf = new BukkitConfigAPI(); + conf = new BukkitViaConfig(); // For compatibility ViaVersion.setInstance(this); diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java similarity index 97% rename from bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java index 74db3b715..014e567e5 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java @@ -11,10 +11,10 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -public class BukkitConfigAPI extends Config implements ViaVersionConfig { +public class BukkitViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); - public BukkitConfigAPI() { + public BukkitViaConfig() { super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml")); // Load config reloadConfig(); @@ -192,7 +192,7 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig { @Override public URL getDefaultConfigURL() { - return BukkitConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); + return BukkitViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml"); } @Override diff --git a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java index 97e3a9c75..72142e311 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java +++ b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java @@ -31,13 +31,13 @@ import java.util.concurrent.TimeUnit; public class BungeePlugin extends Plugin implements ViaPlatform, Listener { private BungeeViaAPI api; - private BungeeConfigAPI config; + private BungeeViaConfig config; private BungeeCommandHandler commandHandler; @Override public void onLoad() { api = new BungeeViaAPI(); - config = new BungeeConfigAPI(getDataFolder()); + config = new BungeeViaConfig(getDataFolder()); commandHandler = new BungeeCommandHandler(); ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler)); // Init platform @@ -134,7 +134,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener { } @Override - public BungeeConfigAPI getConf() { + public BungeeViaConfig getConf() { return config; } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java index fda215417..a6184efa6 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java @@ -3,7 +3,7 @@ package us.myles.ViaVersion.bungee.commands.subs; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.command.ViaCommandSender; import us.myles.ViaVersion.api.command.ViaSubCommand; -import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI; +import us.myles.ViaVersion.bungee.platform.BungeeViaConfig; import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; public class ProbeSubCmd extends ViaSubCommand { @@ -15,7 +15,7 @@ public class ProbeSubCmd extends ViaSubCommand { @Override public String description() { return "Forces ViaVersion to scan server protocol versions " + - (((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ? + (((BungeeViaConfig) Via.getConfig()).getBungeePingInterval() == -1 ? "" : "(Also happens at an interval)"); } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java similarity index 97% rename from bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java rename to bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java index 4f9112099..cdb1ca4c7 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java @@ -9,10 +9,10 @@ import java.io.File; import java.net.URL; import java.util.*; -public class BungeeConfigAPI extends Config implements ViaVersionConfig { +public class BungeeViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); - public BungeeConfigAPI(File configFile) { + public BungeeViaConfig(File configFile) { super(new File(configFile, "config.yml")); // Load config reloadConfig(); @@ -20,7 +20,7 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig { @Override public URL getDefaultConfigURL() { - return BungeeConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); + return BungeeViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml"); } @Override diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java index 252959224..6f5f6a909 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java @@ -6,7 +6,7 @@ import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.api.config.ServerInfo; import us.myles.ViaVersion.BungeePlugin; import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI; +import us.myles.ViaVersion.bungee.platform.BungeeViaConfig; import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider; import java.util.HashMap; @@ -26,7 +26,7 @@ public class ProtocolDetectorService implements Runnable { public static Integer getProtocolId(String serverName) { // Step 1. Check Config - Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); + Map servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols(); Integer protocol = servers.get(serverName); if (protocol != null) { return protocol; @@ -61,8 +61,8 @@ public class ProtocolDetectorService implements Runnable { // Ensure protocol is positive, some services will return -1 if (serverPing.getVersion().getProtocol() > 0) { detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); - if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) { - Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); + if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) { + Map servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols(); Integer protocol = servers.get(key); if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { return; diff --git a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java index 7ca0ac3f6..670dd56ae 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java +++ b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java @@ -17,7 +17,6 @@ import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.text.serializer.TextSerializers; import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.ViaAPI; import us.myles.ViaVersion.api.command.ViaCommandSender; import us.myles.ViaVersion.api.configuration.ConfigurationProvider; import us.myles.ViaVersion.api.platform.TaskId; @@ -32,10 +31,8 @@ import us.myles.ViaVersion.util.GsonUtil; import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.UUID; -import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @Plugin(id = "viaversion", @@ -58,7 +55,7 @@ public class SpongePlugin implements ViaPlatform { @Getter private SpongeViaAPI api = new SpongeViaAPI(); @Getter - private SpongeConfigAPI conf; + private SpongeViaConfig conf; @Getter private Logger logger; @@ -68,7 +65,7 @@ public class SpongePlugin implements ViaPlatform { // Setup Logger logger = new LoggerWrapper(container.getLogger()); // Setup Plugin - conf = new SpongeConfigAPI(container, defaultConfig.getParentFile()); + conf = new SpongeViaConfig(container, defaultConfig.getParentFile()); SpongeCommandHandler commandHandler = new SpongeCommandHandler(); game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge"); getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!"); diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java similarity index 97% rename from sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java rename to sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java index a216b0017..ca8ce5dd6 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java @@ -12,11 +12,11 @@ import java.util.List; import java.util.Map; import java.util.Optional; -public class SpongeConfigAPI extends Config implements ViaVersionConfig { +public class SpongeViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix"); private final PluginContainer pluginContainer; - public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { + public SpongeViaConfig(PluginContainer pluginContainer, File configFile) { super(new File(configFile, "config.yml")); this.pluginContainer = pluginContainer; // Load config From ab1c44c4fb05dca408fcff267aa8118e6c30b73c Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:13:55 +0000 Subject: [PATCH 24/24] Propose 2.0.0 snapshot as this version contains several API breaking changes --- bukkit/pom.xml | 2 +- bungee/pom.xml | 2 +- common/pom.xml | 2 +- jar/pom.xml | 2 +- pom.xml | 2 +- sponge-legacy/pom.xml | 2 +- sponge/pom.xml | 2 +- velocity/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bukkit/pom.xml b/bukkit/pom.xml index 8dda19ea8..3270ff38b 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/bungee/pom.xml b/bungee/pom.xml index d09b21455..384d30083 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/common/pom.xml b/common/pom.xml index 351079c5d..8c4605b9c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/jar/pom.xml b/jar/pom.xml index 95b282a0a..c37896688 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 viaversion-jar diff --git a/pom.xml b/pom.xml index 137071b6e..a9b791357 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ us.myles viaversion-parent - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT pom viaversion-parent diff --git a/sponge-legacy/pom.xml b/sponge-legacy/pom.xml index ac481ad6b..ff4f85e09 100644 --- a/sponge-legacy/pom.xml +++ b/sponge-legacy/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/sponge/pom.xml b/sponge/pom.xml index d9367e0e1..6c651d51d 100644 --- a/sponge/pom.xml +++ b/sponge/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/velocity/pom.xml b/velocity/pom.xml index 50d9a28d5..aa5b4f579 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0